feat(certificate): add certificate type detection and update logic in AddCert and ModifyCert functions

This commit is contained in:
Jacky 2025-04-06 01:08:14 +00:00
parent 440982fc76
commit 771859d3b8
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
6 changed files with 125 additions and 13 deletions

View file

@ -131,6 +131,31 @@ func AddCert(c *gin.Context) {
return return
} }
// Detect and set certificate type
if len(json.SSLCertificate) > 0 {
keyType, err := cert.GetKeyType(json.SSLCertificate)
if err == nil && keyType != "" {
// Set KeyType based on certificate type
switch keyType {
case "2048":
certModel.KeyType = certcrypto.RSA2048
case "3072":
certModel.KeyType = certcrypto.RSA3072
case "4096":
certModel.KeyType = certcrypto.RSA4096
case "P256":
certModel.KeyType = certcrypto.EC256
case "P384":
certModel.KeyType = certcrypto.EC384
}
// Update certificate model
err = certModel.Updates(&model.Cert{KeyType: certModel.KeyType})
if err != nil {
notification.Error("Update Certificate Type Error", err.Error(), nil)
}
}
}
err = cert.SyncToRemoteServer(certModel) err = cert.SyncToRemoteServer(certModel)
if err != nil { if err != nil {
notification.Error("Sync Certificate Error", err.Error(), nil) notification.Error("Sync Certificate Error", err.Error(), nil)
@ -157,7 +182,8 @@ func ModifyCert(c *gin.Context) {
return return
} }
err = certModel.Updates(&model.Cert{ // Create update data object
updateData := &model.Cert{
Name: json.Name, Name: json.Name,
SSLCertificatePath: json.SSLCertificatePath, SSLCertificatePath: json.SSLCertificatePath,
SSLCertificateKeyPath: json.SSLCertificateKeyPath, SSLCertificateKeyPath: json.SSLCertificateKeyPath,
@ -166,11 +192,6 @@ func ModifyCert(c *gin.Context) {
DnsCredentialID: json.DnsCredentialID, DnsCredentialID: json.DnsCredentialID,
ACMEUserID: json.ACMEUserID, ACMEUserID: json.ACMEUserID,
SyncNodeIds: json.SyncNodeIds, SyncNodeIds: json.SyncNodeIds,
})
if err != nil {
cosy.ErrHandler(c, err)
return
} }
content := &cert.Content{ content := &cert.Content{
@ -186,6 +207,32 @@ func ModifyCert(c *gin.Context) {
return return
} }
// Detect and set certificate type
if len(json.SSLCertificate) > 0 {
keyType, err := cert.GetKeyType(json.SSLCertificate)
if err == nil && keyType != "" {
// Set KeyType based on certificate type
switch keyType {
case "2048":
updateData.KeyType = certcrypto.RSA2048
case "3072":
updateData.KeyType = certcrypto.RSA3072
case "4096":
updateData.KeyType = certcrypto.RSA4096
case "P256":
updateData.KeyType = certcrypto.EC256
case "P384":
updateData.KeyType = certcrypto.EC384
}
}
}
err = certModel.Updates(updateData)
if err != nil {
cosy.ErrHandler(c, err)
return
}
err = cert.SyncToRemoteServer(certModel) err = cert.SyncToRemoteServer(certModel)
if err != nil { if err != nil {
notification.Error("Sync Certificate Error", err.Error(), nil) notification.Error("Sync Certificate Error", err.Error(), nil)

View file

@ -33,27 +33,24 @@ const columns: Column[] = [{
if (text === true || text === 1) { if (text === true || text === 1) {
template.push( template.push(
<Tag bordered={false} color="processing"> <Tag bordered={false} color="processing">
{ managed } {managed}
</Tag>, </Tag>,
) )
} }
else if (text === 2) { else if (text === 2) {
template.push( template.push(
<Tag bordered={false} color="success"> <Tag bordered={false} color="success">
{ sync } {sync}
</Tag>, </Tag>,
) )
} }
else { else {
template.push( template.push(
<Tag bordered={false} color="purple"> <Tag bordered={false} color="purple">
{ {general}
general
}
</Tag>, </Tag>,
) )
} }
return h('div', template) return h('div', template)
}, },
sorter: true, sorter: true,

View file

@ -164,7 +164,7 @@ function handleBatchUpdated() {
:get-params="{ :get-params="{
env_group_id: envGroupId, env_group_id: envGroupId,
}" }"
:scroll-x="1200" :scroll-x="1600"
@click-edit="(r: string) => router.push({ @click-edit="(r: string) => router.push({
path: `/sites/${r}`, path: `/sites/${r}`,
})" })"

View file

@ -24,6 +24,7 @@ const columns: Column[] = [{
type: input, type: input,
}, },
search: true, search: true,
width: 150,
}, { }, {
title: () => $gettext('Node Group'), title: () => $gettext('Node Group'),
dataIndex: 'env_group_id', dataIndex: 'env_group_id',

View file

@ -10,4 +10,5 @@ var (
ErrCertParse = e.New(50004, "certificate parse error") ErrCertParse = e.New(50004, "certificate parse error")
ErrPayloadResourceIsNil = e.New(50005, "payload resource is nil") ErrPayloadResourceIsNil = e.New(50005, "payload resource is nil")
ErrPathIsNotUnderTheNginxConfDir = e.New(50006, "path: {0} is not under the nginx conf dir: {1}") ErrPathIsNotUnderTheNginxConfDir = e.New(50006, "path: {0} is not under the nginx conf dir: {1}")
ErrCertPathIsEmpty = e.New(50007, "certificate path is empty")
) )

View file

@ -1,6 +1,8 @@
package cert package cert
import ( import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509" "crypto/x509"
"encoding/pem" "encoding/pem"
"os" "os"
@ -79,3 +81,67 @@ func IsPrivateKeyPath(path string) bool {
return IsPrivateKey(string(bytes)) return IsPrivateKey(string(bytes))
} }
// GetKeyType determines the key type from a PEM certificate string.
// Returns "2048", "3072", "4096", "P256", "P384" or empty string.
func GetKeyType(pemStr string) (string, error) {
block, _ := pem.Decode([]byte(pemStr))
if block == nil {
return "", ErrCertDecode
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return "", ErrCertParse
}
switch cert.PublicKeyAlgorithm {
case x509.RSA:
rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
if !ok {
return "", nil
}
keySize := rsaKey.Size() * 8 // Size returns size in bytes, convert to bits
switch keySize {
case 2048:
return "2048", nil
case 3072:
return "3072", nil
case 4096:
return "4096", nil
default:
return "", nil
}
case x509.ECDSA:
ecKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
if !ok {
return "", nil
}
curve := ecKey.Curve.Params().Name
switch curve {
case "P-256":
return "P256", nil
case "P-384":
return "P384", nil
default:
return "", nil
}
default:
return "", nil
}
}
// GetKeyTypeFromPath determines the key type from a certificate file.
// Returns "2048", "3072", "4096", "P256", "P384" or empty string.
func GetKeyTypeFromPath(path string) (string, error) {
if path == "" {
return "", ErrCertPathIsEmpty
}
bytes, err := os.ReadFile(path)
if err != nil {
return "", err
}
return GetKeyType(string(bytes))
}