1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 00:09:16 +08:00

fix: 解决网站域名可以重复添加的问题 (#2707)

Refs https://github.com/1Panel-dev/1Panel/issues/2636
This commit is contained in:
zhengkunwang 2023-10-27 15:13:25 +08:00 committed by GitHub
parent abedc724df
commit 1ca199ac6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 100 additions and 94 deletions

View File

@ -1,8 +1,6 @@
package v1
import (
"reflect"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
@ -25,7 +23,14 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
if req.All {
list, err := appInstallService.SearchForWebsite(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
} else {
total, list, err := appInstallService.Page(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@ -35,13 +40,6 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
Items: list,
Total: total,
})
} else {
list, err := appInstallService.SearchForWebsite(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
}

View File

@ -195,71 +195,6 @@ func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
helper.SuccessWithData(c, fileInfo)
}
// @Tags Website Domain
// @Summary Search website domains by websiteId
// @Description 通过网站 id 查询域名
// @Accept json
// @Param websiteId path integer true "request"
// @Success 200 {array} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains/:websiteId [get]
func (b *BaseApi) GetWebDomains(c *gin.Context) {
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
list, err := websiteService.GetWebsiteDomain(websiteId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Website Domain
// @Summary Delete website domain
// @Description 删除网站域名
// @Accept json
// @Param request body request.WebsiteDomainDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/domains/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
var req request.WebsiteDomainDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteService.DeleteWebsiteDomain(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website Domain
// @Summary Create website domain
// @Description 创建网站域名
// @Accept json
// @Param request body request.WebsiteDomainCreate true "request"
// @Success 200 {object} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains [post]
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
var req request.WebsiteDomainCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
domain, err := websiteService.CreateWebsiteDomain(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, domain)
}
// @Tags Website Nginx
// @Summary Load nginx conf
// @Description 获取 nginx 配置

View File

@ -0,0 +1,73 @@
package v1
import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin"
)
// @Tags Website Domain
// @Summary Delete website domain
// @Description 删除网站域名
// @Accept json
// @Param request body request.WebsiteDomainDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/domains/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
var req request.WebsiteDomainDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteService.DeleteWebsiteDomain(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website Domain
// @Summary Create website domain
// @Description 创建网站域名
// @Accept json
// @Param request body request.WebsiteDomainCreate true "request"
// @Success 200 {object} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains [post]
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
var req request.WebsiteDomainCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
domain, err := websiteService.CreateWebsiteDomain(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, domain)
}
// @Tags Website Domain
// @Summary Search website domains by websiteId
// @Description 通过网站 id 查询域名
// @Accept json
// @Param websiteId path integer true "request"
// @Success 200 {array} model.WebsiteDomain
// @Security ApiKeyAuth
// @Router /websites/domains/:websiteId [get]
func (b *BaseApi) GetWebDomains(c *gin.Context) {
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
list, err := websiteService.GetWebsiteDomain(websiteId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}

View File

@ -40,6 +40,7 @@ type AppInstalledSearch struct {
Tags []string `json:"tags"`
Update bool `json:"update"`
Unused bool `json:"unused"`
All bool `json:"all"`
}
type AppInstalledInfo struct {

View File

@ -45,7 +45,7 @@ type NewAppInstall struct {
}
type WebsiteInstallCheckReq struct {
InstallIds []uint `json:"InstallIds" validate:"required"`
InstallIds []uint `json:"InstallIds"`
}
type WebsiteUpdate struct {

View File

@ -186,20 +186,6 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
return err
}
defaultHttpPort := nginxInstall.HttpPort
if len(primaryDomainArray) > 1 {
portStr := primaryDomainArray[1]
portN, err := strconv.Atoi(portStr)
if err != nil {
return err
}
if exist, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithDomain(primaryDomain), websiteDomainRepo.WithPort(portN)); len(exist) > 0 {
return buserr.New(constant.ErrDomainIsExist)
}
} else {
if exist, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithDomain(primaryDomain), websiteDomainRepo.WithPort(defaultHttpPort)); len(exist) > 0 {
return buserr.New(constant.ErrDomainIsExist)
}
}
var (
domains []model.WebsiteDomain
@ -224,6 +210,13 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
}
}
for _, domain := range domains {
if exist, _ := websiteDomainRepo.GetFirst(websiteDomainRepo.WithDomain(domain.Domain), websiteDomainRepo.WithPort(domain.Port)); exist.ID > 0 {
website, _ := websiteRepo.GetFirst(commonRepo.WithByID(exist.WebsiteID))
return buserr.WithName(constant.ErrDomainIsUsed, website.PrimaryDomain)
}
}
for port := range ports {
if existPorts, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithPort(port)); len(existPorts) == 0 {
errMap := make(map[string]interface{})
@ -516,8 +509,9 @@ func (w WebsiteService) CreateWebsiteDomain(create request.WebsiteDomainCreate)
}
}
if existDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithDomain(create.Domain), websiteDomainRepo.WithPort(create.Port)); len(existDomains) > 0 {
return domainModel, buserr.WithDetail(constant.ErrDomainIsExist, create.Domain, nil)
if existDomain, _ := websiteDomainRepo.GetFirst(websiteDomainRepo.WithDomain(create.Domain), websiteDomainRepo.WithPort(create.Port)); existDomain.ID > 0 {
website, _ := websiteRepo.GetFirst(commonRepo.WithByID(existDomain.WebsiteID))
return domainModel, buserr.WithName(constant.ErrDomainIsUsed, website.PrimaryDomain)
}
website, err := websiteRepo.GetFirst(commonRepo.WithByID(create.WebsiteID))

View File

@ -71,6 +71,7 @@ var (
ErrUsernameIsNotExist = "ErrUsernameIsNotExist"
ErrBackupMatch = "ErrBackupMatch"
ErrBackupExist = "ErrBackupExist"
ErrDomainIsUsed = "ErrDomainIsUsed"
)
// ssl

View File

@ -75,6 +75,7 @@ ErrBackupMatch: 'the backup file does not match the current partial data of the
ErrBackupExist: 'the backup file corresponds to a portion of the original data that does not exist: {{ .detail}}"'
ErrPHPResource: 'The local runtime does not support switching'
ErrPathPermission: 'A folder with non-1000:1000 permissions was detected in the index directory, which may cause Access denied errors when accessing the website.'
ErrDomainIsUsed: "Domain is already used by website {{ .name }}"
#ssl
ErrSSLCannotDelete: "The certificate is being used by the website and cannot be removed"

View File

@ -75,6 +75,7 @@ ErrBackupMatch: '該備份文件與當前網站部分數據不匹配: {{ .detail
ErrBackupExist: '該備份文件對應部分原數據不存在: {{ .detail}}"'
ErrPHPResource: '本地運行環境不支持切換!'
ErrPathPermission: 'index 目錄下檢測到非 1000:1000 權限文件夾,可能導致網站訪問 Access denied 錯誤'
ErrDomainIsUsed: "域名已被網站【{{ .name }}】使用"
#ssl
ErrSSLCannotDelete: "證書正在被網站使用,無法刪除"

View File

@ -75,6 +75,7 @@ ErrBackupMatch: '该备份文件与当前网站部分数据不匹配 {{ .detail}
ErrBackupExist: '该备份文件对应部分源数据不存在 {{ .detail}}"'
ErrPHPResource: '本地运行环境不支持切换!'
ErrPathPermission: 'index 目录下检测到非 1000:1000 权限文件夹,可能导致网站访问 Access denied 错误'
ErrDomainIsUsed: "域名已被网站【{{ .name }}】使用"
#ssl
ErrSSLCannotDelete: "证书正在被网站使用,无法删除"

View File

@ -161,9 +161,10 @@ export namespace App {
deleteBackup?: boolean;
}
export interface AppInstalledSearch {
export interface AppInstalledSearch extends ReqPage {
type: string;
unused?: boolean;
all?: boolean;
}
export interface AppService {

View File

@ -458,7 +458,7 @@ const changeType = (type: string) => {
};
const searchAppInstalled = () => {
GetAppInstalled({ type: 'website', unused: true }).then((res) => {
GetAppInstalled({ type: 'website', unused: true, all: true, page: 1, pageSize: 100 }).then((res) => {
appInstalles.value = res.data;
if (res.data && res.data.length > 0) {
website.value.appInstallId = res.data[0].id;