mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-08 22:46:51 +08:00
feat: add openBaseDir for php website config (#8866)
This commit is contained in:
parent
a4d63434cb
commit
71d92c30e3
17 changed files with 127 additions and 22 deletions
|
@ -1101,3 +1101,23 @@ func (b *BaseApi) ClearProxyCache(c *gin.Context) {
|
|||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Operate Cross Site Access
|
||||
// @Accept json
|
||||
// @Param request body request.CrossSiteAccessOp true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /websites/crosssite [post]
|
||||
func (b *BaseApi) OperateCrossSiteAccess(c *gin.Context) {
|
||||
var req request.CrossSiteAccessOp
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteService.OperateCrossSiteAccess(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
|
|
@ -289,3 +289,8 @@ type WebsiteProxyDel struct {
|
|||
ID uint `json:"id" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type CrossSiteAccessOp struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Operation string `json:"operation" validate:"required,oneof=Enable Disable"`
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ type WebsiteDTO struct {
|
|||
RuntimeName string `json:"runtimeName"`
|
||||
RuntimeType string `json:"runtimeType"`
|
||||
SiteDir string `json:"siteDir"`
|
||||
OpenBaseDir bool `json:"openBaseDir"`
|
||||
}
|
||||
|
||||
type WebsiteRes struct {
|
||||
|
|
|
@ -124,6 +124,8 @@ type IWebsiteService interface {
|
|||
GetWebsiteResource(websiteID uint) ([]response.Resource, error)
|
||||
ListDatabases() ([]response.Database, error)
|
||||
ChangeDatabase(req request.ChangeDatabase) error
|
||||
|
||||
OperateCrossSiteAccess(req request.CrossSiteAccessOp) error
|
||||
}
|
||||
|
||||
func NewIWebsiteService() IWebsiteService {
|
||||
|
@ -428,7 +430,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
|
|||
return err
|
||||
}
|
||||
if runtime.Type == constant.RuntimePHP && runtime.Resource == constant.ResourceAppstore {
|
||||
createPHPConfig(website)
|
||||
createOpenBasedirConfig(website)
|
||||
}
|
||||
}
|
||||
tx, ctx := helper.GetTxAndContext()
|
||||
|
@ -573,6 +575,9 @@ func (w WebsiteService) GetWebsite(id uint) (response.WebsiteDTO, error) {
|
|||
}
|
||||
res.RuntimeType = runtime.Type
|
||||
res.RuntimeName = runtime.Name
|
||||
if runtime.Type == constant.RuntimePHP {
|
||||
res.OpenBaseDir = files.NewFileOp().Stat(path.Join(GetSitePath(website, SiteIndexDir), ".user.ini"))
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
@ -3278,3 +3283,18 @@ func (w WebsiteService) ChangeDatabase(req request.ChangeDatabase) error {
|
|||
website.DbType = req.DatabaseType
|
||||
return websiteRepo.Save(context.Background(), &website)
|
||||
}
|
||||
|
||||
func (w WebsiteService) OperateCrossSiteAccess(req request.CrossSiteAccessOp) error {
|
||||
website, err := websiteRepo.GetFirst(repo.WithByID(req.WebsiteID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Operation == constant.StatusEnable {
|
||||
createOpenBasedirConfig(&website)
|
||||
}
|
||||
if req.Operation == constant.StatusDisable {
|
||||
fileOp := files.NewFileOp()
|
||||
return fileOp.DeleteFile(path.Join(GetSitePath(website, SiteIndexDir), ".user.ini"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -349,11 +349,11 @@ func createAllWebsitesWAFConfig(websites []model.Website) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func createPHPConfig(website *model.Website) {
|
||||
func createOpenBasedirConfig(website *model.Website) {
|
||||
fileOp := files.NewFileOp()
|
||||
userIniPath := path.Join(GetSitePath(*website, SiteIndexDir), ".user.ini")
|
||||
_ = fileOp.CreateFile(userIniPath)
|
||||
_ = fileOp.SaveFile(userIniPath, fmt.Sprintf("open_basedir=/www/sites/%s/index", website.Alias), 0644)
|
||||
_ = fileOp.SaveFile(userIniPath, fmt.Sprintf("open_basedir=/www/sites/%s/index:/tmp/", website.Alias), 0644)
|
||||
}
|
||||
|
||||
func createWafConfig(website *model.Website, domains []model.WebsiteDomain) error {
|
||||
|
|
|
@ -84,5 +84,7 @@ func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) {
|
|||
websiteRouter.GET("/resource/:id", baseApi.GetWebsiteResource)
|
||||
websiteRouter.GET("/databases", baseApi.GetWebsiteDatabase)
|
||||
websiteRouter.POST("/databases", baseApi.ChangeWebsiteDatabase)
|
||||
|
||||
websiteRouter.POST("/crosssite", baseApi.OperateCrossSiteAccess)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ export namespace Website {
|
|||
appName: string;
|
||||
runtimeName: string;
|
||||
runtimeType: string;
|
||||
openBaseDir: boolean;
|
||||
}
|
||||
export interface WebsiteRes extends CommonModel {
|
||||
protocol: string;
|
||||
|
@ -646,4 +647,9 @@ export namespace Website {
|
|||
databaseID: number;
|
||||
databaseType: string;
|
||||
}
|
||||
|
||||
export interface CrossSiteAccessOp {
|
||||
websiteID: number;
|
||||
operation: string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,3 +343,7 @@ export const operateCustomRewrite = (req: Website.CustomRewirte) => {
|
|||
export const listCustomRewrite = () => {
|
||||
return http.get<string[]>(`/websites/rewrite/custom`);
|
||||
};
|
||||
|
||||
export const operateCrossSiteAccess = (req: Website.CrossSiteAccessOp) => {
|
||||
return http.post(`/websites/crosssite`, req);
|
||||
};
|
||||
|
|
|
@ -2476,6 +2476,9 @@ const message = {
|
|||
useProxy: 'Use Proxy',
|
||||
useProxyHelper: 'Use the proxy server address in the panel settings',
|
||||
westCN: 'West Digital',
|
||||
openBaseDir: 'Prevent Cross-Site Attacks',
|
||||
openBaseDirHelper:
|
||||
'open_basedir is used to restrict the PHP file access path, which helps prevent cross-site access and enhance security',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Short tag support',
|
||||
|
|
|
@ -2382,6 +2382,9 @@ const message = {
|
|||
useProxy: 'プロキシを使用',
|
||||
useProxyHelper: 'パネル設定のプロキシサーバーアドレスを使用',
|
||||
westCN: '西部デジタル',
|
||||
openBaseDir: 'クロスサイト攻撃を防ぐ',
|
||||
openBaseDirHelper:
|
||||
'open_basedir は PHP ファイルのアクセスパスを制限し、クロスサイトアクセスを防ぎセキュリティを向上させるために使用されます',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短いタグサポート',
|
||||
|
|
|
@ -2341,6 +2341,9 @@ const message = {
|
|||
useProxy: '프록시 사용',
|
||||
useProxyHelper: '패널 설정의 프록시 서버 주소 사용',
|
||||
westCN: '서부 디지털',
|
||||
openBaseDir: '사이트 간 공격 방지',
|
||||
openBaseDirHelper:
|
||||
'open_basedir는 PHP 파일 액세스 경로를 제한하여 사이트 간 액세스를 방지하고 보안을 향상시키는 데 사용됩니다',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '짧은 태그 지원',
|
||||
|
|
|
@ -2436,6 +2436,9 @@ const message = {
|
|||
useProxy: 'Gunakan Proksi',
|
||||
useProxyHelper: 'Gunakan alamat pelayan proksi dalam tetapan panel',
|
||||
westCN: 'West Digital',
|
||||
openBaseDir: 'Pencegahan Serangan Lintas Situs',
|
||||
openBaseDirHelper:
|
||||
'open_basedir digunakan untuk membatasi jalur akses file PHP, yang membantu mencegah akses lintas situs dan meningkatkan keamanan',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Sokongan tag pendek',
|
||||
|
|
|
@ -2433,6 +2433,9 @@ const message = {
|
|||
useProxy: 'Usar Proxy',
|
||||
useProxyHelper: 'Usar o endereço do servidor proxy nas configurações do painel',
|
||||
westCN: 'West Digital',
|
||||
openBaseDir: 'Prevenir Ataques entre Sites',
|
||||
openBaseDirHelper:
|
||||
'open_basedir é usado para restringir o caminho de acesso a arquivos PHP, ajudando a prevenir acesso entre sites e aumentar a segurança',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Suporte para short tags',
|
||||
|
|
|
@ -2432,6 +2432,9 @@ const message = {
|
|||
useProxy: 'Использовать прокси',
|
||||
useProxyHelper: 'Использовать адрес прокси-сервера в настройках панели',
|
||||
westCN: 'Западный цифровой',
|
||||
openBaseDir: 'Предотвращение межсайтовых атак',
|
||||
openBaseDirHelper:
|
||||
'open_basedir используется для ограничения пути доступа к файлам PHP, что помогает предотвратить межсайтовый доступ и повысить безопасность',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: 'Поддержка коротких тегов',
|
||||
|
|
|
@ -2296,6 +2296,8 @@ const message = {
|
|||
useProxy: '使用代理',
|
||||
useProxyHelper: '使用面板設置中的代理服務器地址',
|
||||
westCN: '西部數碼',
|
||||
openBaseDir: '防跨站攻擊',
|
||||
openBaseDirHelper: 'open_basedir 用於限制 PHP 文件訪問路徑,有助於防止跨站訪問和提升安全性',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短標簽支持',
|
||||
|
|
|
@ -2286,6 +2286,8 @@ const message = {
|
|||
useProxy: '使用代理',
|
||||
useProxyHelper: '使用面板设置中的代理服务器地址',
|
||||
westCN: '西部数码',
|
||||
openBaseDir: '防跨站攻击',
|
||||
openBaseDirHelper: 'open_basedir 用于限制 PHP 文件访问路径,有助于防止跨站访问和提升安全性',
|
||||
},
|
||||
php: {
|
||||
short_open_tag: '短标签支持',
|
||||
|
|
|
@ -2,28 +2,39 @@
|
|||
<div v-loading="loading">
|
||||
<el-row>
|
||||
<el-col :xs="20" :sm="12" :md="10" :lg="10" :xl="8">
|
||||
<el-form label-position="right" label-width="80px">
|
||||
<el-form label-position="right" label-width="120px">
|
||||
<el-form-item>
|
||||
<div v-if="website.type === 'static'">
|
||||
<el-text type="info">{{ $t('website.staticChangePHPHelper') }}</el-text>
|
||||
</div>
|
||||
<el-text type="info" v-if="website.type === 'static'">
|
||||
{{ $t('website.staticChangePHPHelper') }}
|
||||
</el-text>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('website.changeVersion')">
|
||||
<el-select v-model="versionReq.runtimeID" class="w-full">
|
||||
<el-option :key="-1" :label="$t('website.static')" :value="0"></el-option>
|
||||
<el-option
|
||||
v-for="(item, index) in versions"
|
||||
:key="index"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="20">
|
||||
<el-select v-model="versionReq.runtimeID" class="p-w-200">
|
||||
<el-option :key="-1" :label="$t('website.static')" :value="0"></el-option>
|
||||
<el-option
|
||||
v-for="(item, index) in versions"
|
||||
:key="index"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submit()"
|
||||
:disabled="versionReq.runtimeID === oldRuntimeID"
|
||||
>
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit()" :disabled="versionReq.runtimeID === oldRuntimeID">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
<el-form-item :label="$t('website.openBaseDir')">
|
||||
<el-switch v-model="openBaseDir" @change="operateCrossSite"></el-switch>
|
||||
<span class="input-help">{{ $t('website.openBaseDirHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
|
@ -36,7 +47,7 @@ import { SearchRuntimes } from '@/api/modules/runtime';
|
|||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Runtime } from '@/api/interface/runtime';
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { changePHPVersion, getWebsite } from '@/api/modules/website';
|
||||
import { changePHPVersion, getWebsite, operateCrossSiteAccess } from '@/api/modules/website';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
const props = defineProps({
|
||||
|
@ -56,7 +67,9 @@ const loading = ref(false);
|
|||
const oldRuntimeID = ref(0);
|
||||
const website = ref({
|
||||
type: '',
|
||||
openBaseDir: false,
|
||||
});
|
||||
const openBaseDir = ref(false);
|
||||
|
||||
const getRuntimes = async () => {
|
||||
try {
|
||||
|
@ -95,6 +108,18 @@ const getWebsiteDetail = async () => {
|
|||
versionReq.runtimeID = res.data.runtimeID;
|
||||
oldRuntimeID.value = res.data.runtimeID;
|
||||
website.value = res.data;
|
||||
openBaseDir.value = res.data.openBaseDir || false;
|
||||
};
|
||||
|
||||
const operateCrossSite = async () => {
|
||||
try {
|
||||
await operateCrossSiteAccess({
|
||||
websiteID: props.id,
|
||||
operation: openBaseDir.value ? 'Enable' : 'Disable',
|
||||
});
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
getWebsiteDetail();
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
Loading…
Add table
Reference in a new issue