mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-09-11 09:05:51 +08:00
feat(system): Fix issue with certificate failure in settings panel (#8063)
This commit is contained in:
parent
6092e768ef
commit
7a6e5376c4
10 changed files with 173 additions and 11 deletions
|
@ -113,11 +113,12 @@ func (b *BaseApi) ObtainWebsiteCA(c *gin.Context) {
|
|||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err := websiteCAService.ObtainSSL(req); err != nil {
|
||||
res, err := websiteCAService.ObtainSSL(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website CA
|
||||
|
|
47
core/app/model/agent.go
Normal file
47
core/app/model/agent.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type WebsiteSSL struct {
|
||||
BaseModel
|
||||
PrimaryDomain string `json:"primaryDomain"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Pem string `json:"pem"`
|
||||
Domains string `json:"domains"`
|
||||
CertURL string `json:"certURL"`
|
||||
Type string `json:"type"`
|
||||
Provider string `json:"provider"`
|
||||
Organization string `json:"organization"`
|
||||
DnsAccountID uint `json:"dnsAccountId"`
|
||||
AcmeAccountID uint `gorm:"column:acme_account_id" json:"acmeAccountId" `
|
||||
CaID uint `json:"caId"`
|
||||
AutoRenew bool `json:"autoRenew"`
|
||||
ExpireDate time.Time `json:"expireDate"`
|
||||
StartDate time.Time `json:"startDate"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
KeyType string `json:"keyType"`
|
||||
PushDir bool `json:"pushDir"`
|
||||
Dir string `json:"dir"`
|
||||
Description string `json:"description"`
|
||||
SkipDNS bool `json:"skipDNS"`
|
||||
Nameserver1 string `json:"nameserver1"`
|
||||
Nameserver2 string `json:"nameserver2"`
|
||||
DisableCNAME bool `json:"disableCNAME"`
|
||||
ExecShell bool `json:"execShell"`
|
||||
Shell string `json:"shell"`
|
||||
}
|
||||
|
||||
func (w WebsiteSSL) TableName() string {
|
||||
return "website_ssls"
|
||||
}
|
||||
|
||||
type WebsiteCA struct {
|
||||
BaseModel
|
||||
CSR string `gorm:"not null;" json:"csr"`
|
||||
Name string `gorm:"not null;" json:"name"`
|
||||
PrivateKey string `gorm:"not null" json:"privateKey"`
|
||||
KeyType string `gorm:"not null;default:2048" json:"keyType"`
|
||||
}
|
37
core/app/repo/agent.go
Normal file
37
core/app/repo/agent.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
)
|
||||
|
||||
type AgentRepo struct{}
|
||||
|
||||
type IAgentRepo interface {
|
||||
GetWebsiteSSL(opts ...global.DBOption) (model.WebsiteSSL, error)
|
||||
GetCA(opts ...global.DBOption) (model.WebsiteCA, error)
|
||||
}
|
||||
|
||||
func NewIAgentRepo() IAgentRepo {
|
||||
return &AgentRepo{}
|
||||
}
|
||||
|
||||
func (a *AgentRepo) GetWebsiteSSL(opts ...global.DBOption) (model.WebsiteSSL, error) {
|
||||
var ssl model.WebsiteSSL
|
||||
db := global.AgentDB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&ssl).Error
|
||||
return ssl, err
|
||||
}
|
||||
|
||||
func (a *AgentRepo) GetCA(opts ...global.DBOption) (model.WebsiteCA, error) {
|
||||
var ca model.WebsiteCA
|
||||
db := global.AgentDB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&ca).Error
|
||||
return ca, err
|
||||
}
|
|
@ -13,4 +13,6 @@ var (
|
|||
upgradeLogRepo = repo.NewIUpgradeLogRepo()
|
||||
|
||||
taskRepo = repo.NewITaskRepo()
|
||||
|
||||
agentRepo = repo.NewIAgentRepo()
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
|
@ -8,7 +9,10 @@ import (
|
|||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/req_helper"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
@ -265,6 +269,48 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
|
|||
return err
|
||||
}
|
||||
secret = string(certFile)
|
||||
case "select":
|
||||
ssl, err := agentRepo.GetWebsiteSSL(repo.WithByID(req.SSLID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret = ssl.Pem
|
||||
key = ssl.PrivateKey
|
||||
if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil {
|
||||
return err
|
||||
}
|
||||
case "self":
|
||||
ca, err := agentRepo.GetCA(repo.WithByName("1Panel"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params := make(map[string]interface{})
|
||||
params["domains"] = req.Domain
|
||||
params["time"] = 10
|
||||
params["unit"] = "year"
|
||||
params["keyType"] = "P256"
|
||||
params["id"] = ca.ID
|
||||
jsonData, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := req_helper.NewLocalClient("/api/v2/websites/ca/obtain", http.MethodPost, bytes.NewReader(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonBytes, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var ssl model.WebsiteSSL
|
||||
if err := json.Unmarshal(jsonBytes, &ssl); err != nil {
|
||||
return err
|
||||
}
|
||||
secret = ssl.Pem
|
||||
key = ssl.PrivateKey
|
||||
if err := settingRepo.Update("SSLID", strconv.Itoa(int(ssl.ID))); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path.Join(secretDir, "server.crt.tmp"), []byte(secret), 0600); err != nil {
|
||||
|
@ -325,7 +371,18 @@ func (u *SettingService) LoadFromCert() (*dto.SSLInfo, error) {
|
|||
keyFile, _ := os.ReadFile(path.Join(global.CONF.Base.InstallDir, "1panel/secret/server.key"))
|
||||
data.Key = string(keyFile)
|
||||
case "select":
|
||||
// TODO select ssl from website
|
||||
sslID, err := settingRepo.Get(repo.WithByKey("SSLID"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id, _ := strconv.Atoi(sslID.Value)
|
||||
ssl, err := agentRepo.GetWebsiteSSL(repo.WithByID(uint(id)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data.Domain = ssl.PrimaryDomain
|
||||
data.SSLID = uint(id)
|
||||
data.Timeout = ssl.ExpireDate.Format(constant.DateTimeLayout)
|
||||
}
|
||||
return &data, nil
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
var (
|
||||
DB *gorm.DB
|
||||
TaskDB *gorm.DB
|
||||
AgentDB *gorm.DB
|
||||
LOG *logrus.Logger
|
||||
CONF ServerConfig
|
||||
Api ApiInterface
|
||||
|
|
|
@ -10,4 +10,5 @@ import (
|
|||
func Init() {
|
||||
global.DB = common.LoadDBConnByPath(path.Join(global.CONF.Base.InstallDir, "1panel/db/core.db"), "core")
|
||||
global.TaskDB = common.LoadDBConnByPath(path.Join(global.CONF.Base.InstallDir, "1panel/db/task.db"), "task")
|
||||
global.AgentDB = common.LoadDBConnByPath(path.Join(global.CONF.Base.InstallDir, "1panel/db/agent.db"), "agent")
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ class RequestHttp {
|
|||
'Accept-Language': language,
|
||||
...config.headers,
|
||||
};
|
||||
config.headers.CurrentNode = globalStore.currentNode;
|
||||
if (config.headers.CurrentNode == undefined) {
|
||||
config.headers.CurrentNode = globalStore.currentNode;
|
||||
}
|
||||
if (config.url === '/core/auth/login' || config.url === '/core/auth/mfalogin') {
|
||||
let entrance = Base64.encode(globalStore.entrance);
|
||||
config.headers.EntranceCode = entrance;
|
||||
|
@ -125,6 +127,16 @@ class RequestHttp {
|
|||
withCredentials: true,
|
||||
});
|
||||
}
|
||||
postLocalNode<T>(url: string, params?: object, timeout?: number): Promise<ResultData<T>> {
|
||||
return this.service.post(url, params, {
|
||||
baseURL: import.meta.env.VITE_API_URL as string,
|
||||
timeout: timeout ? timeout : (ResultEnum.TIMEOUT as number),
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
CurrentNode: 'local',
|
||||
},
|
||||
});
|
||||
}
|
||||
put<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
|
||||
return this.service.put(url, params, _object);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,10 @@ export const listSSL = (req: Website.SSLReq) => {
|
|||
return http.post<Website.SSLDTO[]>(`/websites/ssl/search`, req);
|
||||
};
|
||||
|
||||
export const listLocalNodeSSL = (req: Website.SSLReq) => {
|
||||
return http.postLocalNode<Website.SSLDTO[]>(`/websites/ssl/search`, req);
|
||||
};
|
||||
|
||||
export const createSSL = (req: Website.SSLCreate) => {
|
||||
return http.post<Website.SSLCreate>(`/websites/ssl`, req, TimeoutEnum.T_10M);
|
||||
};
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
|
||||
<el-form-item v-if="form.timeout">
|
||||
<el-tag>{{ $t('setting.domainOrIP') }} {{ form.domain }}</el-tag>
|
||||
<el-tag style="margin-left: 5px">{{ $t('setting.timeOut') }} {{ form.timeout }}</el-tag>
|
||||
<el-tag class="p-ml-5">{{ $t('setting.timeOut') }} {{ form.timeout }}</el-tag>
|
||||
<el-button
|
||||
@click="onDownload"
|
||||
style="margin-left: 5px"
|
||||
class="p-ml-5"
|
||||
v-if="form.sslType === 'self'"
|
||||
type="primary"
|
||||
link
|
||||
|
@ -116,7 +116,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { dateFormatSimple, getProvider } from '@/utils/util';
|
||||
import { listSSL } from '@/api/modules/website';
|
||||
import { listLocalNodeSSL } from '@/api/modules/website';
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
@ -131,7 +131,7 @@ const loading = ref();
|
|||
const drawerVisible = ref();
|
||||
|
||||
const form = reactive({
|
||||
ssl: 'enable',
|
||||
ssl: 'Enable',
|
||||
domain: '',
|
||||
sslType: 'self',
|
||||
itemSSLType: 'paste',
|
||||
|
@ -172,7 +172,7 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
|
|||
|
||||
if (params.sslInfo?.sslID) {
|
||||
form.sslID = params.sslInfo.sslID;
|
||||
const ssls = await listSSL({});
|
||||
const ssls = await listLocalNodeSSL({});
|
||||
sslList.value = ssls.data || [];
|
||||
changeSSl(params.sslInfo?.sslID);
|
||||
} else {
|
||||
|
@ -183,7 +183,7 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
|
|||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const loadSSLs = async () => {
|
||||
const res = await listSSL({});
|
||||
const res = await listLocalNodeSSL({});
|
||||
sslList.value = res.data || [];
|
||||
};
|
||||
|
||||
|
@ -228,7 +228,7 @@ const onSaveSSL = async (formEl: FormInstance | undefined) => {
|
|||
itemType = form.itemSSLType === 'paste' ? 'import-paste' : 'import-local';
|
||||
}
|
||||
let param = {
|
||||
ssl: 'enable',
|
||||
ssl: 'Enable',
|
||||
sslType: itemType,
|
||||
domain: '',
|
||||
sslID: form.sslID,
|
||||
|
|
Loading…
Add table
Reference in a new issue