feat: add a option to select a acme user when obtaining a certificate.

This commit is contained in:
Jacky 2024-04-30 11:16:30 +08:00
parent e77d37bbaa
commit f0dcd67004
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
8 changed files with 186 additions and 2 deletions

View file

@ -85,6 +85,7 @@ type certJson struct {
KeyType certcrypto.KeyType `json:"key_type" binding:"omitempty,auto_cert_key_type"` KeyType certcrypto.KeyType `json:"key_type" binding:"omitempty,auto_cert_key_type"`
ChallengeMethod string `json:"challenge_method"` ChallengeMethod string `json:"challenge_method"`
DnsCredentialID int `json:"dns_credential_id"` DnsCredentialID int `json:"dns_credential_id"`
ACMEUserID int `json:"acme_user_id"`
} }
func AddCert(c *gin.Context) { func AddCert(c *gin.Context) {
@ -101,6 +102,7 @@ func AddCert(c *gin.Context) {
KeyType: json.KeyType, KeyType: json.KeyType,
ChallengeMethod: json.ChallengeMethod, ChallengeMethod: json.ChallengeMethod,
DnsCredentialID: json.DnsCredentialID, DnsCredentialID: json.DnsCredentialID,
ACMEUserID: json.ACMEUserID,
} }
err := certModel.Insert() err := certModel.Insert()
@ -151,6 +153,7 @@ func ModifyCert(c *gin.Context) {
ChallengeMethod: json.ChallengeMethod, ChallengeMethod: json.ChallengeMethod,
KeyType: json.KeyType, KeyType: json.KeyType,
DnsCredentialID: json.DnsCredentialID, DnsCredentialID: json.DnsCredentialID,
ACMEUserID: json.ACMEUserID,
}) })
if err != nil { if err != nil {

View file

@ -1,6 +1,7 @@
import type { ModelBase } from '@/api/curd' import type { ModelBase } from '@/api/curd'
import Curd from '@/api/curd' import Curd from '@/api/curd'
import type { DnsCredential } from '@/api/dns_credential' import type { DnsCredential } from '@/api/dns_credential'
import type { AcmeUser } from '@/api/acme_user'
export interface Cert extends ModelBase { export interface Cert extends ModelBase {
name: string name: string
@ -14,6 +15,8 @@ export interface Cert extends ModelBase {
challenge_method: string challenge_method: string
dns_credential_id: number dns_credential_id: number
dns_credential?: DnsCredential dns_credential?: DnsCredential
acme_user_id: number
acme_user?: AcmeUser
key_type: string key_type: string
log: string log: string
certificate_info: CertificateInfo certificate_info: CertificateInfo

View file

@ -0,0 +1,86 @@
<script setup lang="ts">
import type { SelectProps } from 'ant-design-vue'
import type { Ref } from 'vue'
import type { AcmeUser } from '@/api/acme_user'
import acme_user from '@/api/acme_user'
import type { Cert } from '@/api/cert'
const users = ref([]) as Ref<AcmeUser[]>
// This data is provided by the Top StdCurd component,
// is the object that you are trying to modify it
// we externalize the dns_credential_id to the parent component,
// this is used to tell the backend which dns_credential to use
const data = inject('data') as Ref<Cert>
const id = computed(() => {
return data.value.acme_user_id
})
const user_idx = ref()
function init() {
users.value?.forEach((v: AcmeUser, k: number) => {
if (v.id === id.value)
user_idx.value = k
})
}
const current = computed(() => {
return users.value?.[user_idx.value]
})
const mounted = ref(false)
watch(id, init)
watch(current, () => {
data.value.acme_user_id = current.value.id
if (!mounted.value)
data.value.acme_user_id = 0
})
onMounted(async () => {
await acme_user.get_list().then(r => {
users.value = r.data
}).then(() => {
init()
})
// prevent the acme_user_id from being overwritten
mounted.value = true
})
const options = computed<SelectProps['options']>(() => {
const list: SelectProps['options'] = []
users.value.forEach((v, k: number) => {
list!.push({
value: k,
label: v.name,
})
})
return list
})
const filterOption = (input: string, option: { label: string }) => {
return option.label.toLowerCase().includes(input.toLowerCase())
}
</script>
<template>
<AForm layout="vertical">
<AFormItem :label="$gettext('ACME User')">
<ASelect
v-model:value="user_idx"
show-search
:options="options"
:filter-option="filterOption"
/>
</AFormItem>
</AForm>
</template>
<style lang="less" scoped>
</style>

View file

@ -137,6 +137,7 @@ const refTable = ref()
ref="refTable" ref="refTable"
:api="cert" :api="cert"
:columns="columns" :columns="columns"
disabled-view
@click-edit="id => $router.push(`/certificates/${id}`)" @click-edit="id => $router.push(`/certificates/${id}`)"
/> />
<WildcardCertificate <WildcardCertificate

View file

@ -3,6 +3,7 @@ import type { Ref } from 'vue'
import type { DnsChallenge } from '@/api/auto_cert' import type { DnsChallenge } from '@/api/auto_cert'
import DNSChallenge from '@/views/domain/cert/components/DNSChallenge.vue' import DNSChallenge from '@/views/domain/cert/components/DNSChallenge.vue'
import type { Cert } from '@/api/cert' import type { Cert } from '@/api/cert'
import ACMEUserSelector from '@/views/certificate/ACMEUserSelector.vue'
defineProps<{ defineProps<{
hideNote?: boolean hideNote?: boolean
@ -114,6 +115,7 @@ onMounted(() => {
</ASelect> </ASelect>
</AFormItem> </AFormItem>
</AForm> </AForm>
<ACMEUserSelector />
<DNSChallenge v-if="data.challenge_method === 'dns01'" /> <DNSChallenge v-if="data.challenge_method === 'dns01'" />
</div> </div>
</template> </template>

View file

@ -27,6 +27,8 @@ type Cert struct {
ChallengeMethod string `json:"challenge_method"` ChallengeMethod string `json:"challenge_method"`
DnsCredentialID int `json:"dns_credential_id"` DnsCredentialID int `json:"dns_credential_id"`
DnsCredential *DnsCredential `json:"dns_credential,omitempty"` DnsCredential *DnsCredential `json:"dns_credential,omitempty"`
ACMEUserID int `json:"acme_user_id"`
ACMEUser *AcmeUser `json:"acme_user,omitempty"`
KeyType certcrypto.KeyType `json:"key_type"` KeyType certcrypto.KeyType `json:"key_type"`
Log string `json:"log"` Log string `json:"log"`
} }

View file

@ -36,6 +36,7 @@ func newAcmeUser(db *gorm.DB, opts ...gen.DOOption) acmeUser {
_acmeUser.Email = field.NewString(tableName, "email") _acmeUser.Email = field.NewString(tableName, "email")
_acmeUser.CADir = field.NewString(tableName, "ca_dir") _acmeUser.CADir = field.NewString(tableName, "ca_dir")
_acmeUser.Registration = field.NewField(tableName, "registration") _acmeUser.Registration = field.NewField(tableName, "registration")
_acmeUser.Key = field.NewField(tableName, "key")
_acmeUser.fillFieldMap() _acmeUser.fillFieldMap()
@ -54,6 +55,7 @@ type acmeUser struct {
Email field.String Email field.String
CADir field.String CADir field.String
Registration field.Field Registration field.Field
Key field.Field
fieldMap map[string]field.Expr fieldMap map[string]field.Expr
} }
@ -78,6 +80,7 @@ func (a *acmeUser) updateTableName(table string) *acmeUser {
a.Email = field.NewString(table, "email") a.Email = field.NewString(table, "email")
a.CADir = field.NewString(table, "ca_dir") a.CADir = field.NewString(table, "ca_dir")
a.Registration = field.NewField(table, "registration") a.Registration = field.NewField(table, "registration")
a.Key = field.NewField(table, "key")
a.fillFieldMap() a.fillFieldMap()
@ -94,7 +97,7 @@ func (a *acmeUser) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
} }
func (a *acmeUser) fillFieldMap() { func (a *acmeUser) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 8) a.fieldMap = make(map[string]field.Expr, 9)
a.fieldMap["id"] = a.ID a.fieldMap["id"] = a.ID
a.fieldMap["created_at"] = a.CreatedAt a.fieldMap["created_at"] = a.CreatedAt
a.fieldMap["updated_at"] = a.UpdatedAt a.fieldMap["updated_at"] = a.UpdatedAt
@ -103,6 +106,7 @@ func (a *acmeUser) fillFieldMap() {
a.fieldMap["email"] = a.Email a.fieldMap["email"] = a.Email
a.fieldMap["ca_dir"] = a.CADir a.fieldMap["ca_dir"] = a.CADir
a.fieldMap["registration"] = a.Registration a.fieldMap["registration"] = a.Registration
a.fieldMap["key"] = a.Key
} }
func (a acmeUser) clone(db *gorm.DB) acmeUser { func (a acmeUser) clone(db *gorm.DB) acmeUser {

View file

@ -40,6 +40,7 @@ func newCert(db *gorm.DB, opts ...gen.DOOption) cert {
_cert.AutoCert = field.NewInt(tableName, "auto_cert") _cert.AutoCert = field.NewInt(tableName, "auto_cert")
_cert.ChallengeMethod = field.NewString(tableName, "challenge_method") _cert.ChallengeMethod = field.NewString(tableName, "challenge_method")
_cert.DnsCredentialID = field.NewInt(tableName, "dns_credential_id") _cert.DnsCredentialID = field.NewInt(tableName, "dns_credential_id")
_cert.ACMEUserID = field.NewInt(tableName, "acme_user_id")
_cert.KeyType = field.NewString(tableName, "key_type") _cert.KeyType = field.NewString(tableName, "key_type")
_cert.Log = field.NewString(tableName, "log") _cert.Log = field.NewString(tableName, "log")
_cert.DnsCredential = certBelongsToDnsCredential{ _cert.DnsCredential = certBelongsToDnsCredential{
@ -48,6 +49,12 @@ func newCert(db *gorm.DB, opts ...gen.DOOption) cert {
RelationField: field.NewRelation("DnsCredential", "model.DnsCredential"), RelationField: field.NewRelation("DnsCredential", "model.DnsCredential"),
} }
_cert.ACMEUser = certBelongsToACMEUser{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("ACMEUser", "model.AcmeUser"),
}
_cert.fillFieldMap() _cert.fillFieldMap()
return _cert return _cert
@ -69,10 +76,13 @@ type cert struct {
AutoCert field.Int AutoCert field.Int
ChallengeMethod field.String ChallengeMethod field.String
DnsCredentialID field.Int DnsCredentialID field.Int
ACMEUserID field.Int
KeyType field.String KeyType field.String
Log field.String Log field.String
DnsCredential certBelongsToDnsCredential DnsCredential certBelongsToDnsCredential
ACMEUser certBelongsToACMEUser
fieldMap map[string]field.Expr fieldMap map[string]field.Expr
} }
@ -100,6 +110,7 @@ func (c *cert) updateTableName(table string) *cert {
c.AutoCert = field.NewInt(table, "auto_cert") c.AutoCert = field.NewInt(table, "auto_cert")
c.ChallengeMethod = field.NewString(table, "challenge_method") c.ChallengeMethod = field.NewString(table, "challenge_method")
c.DnsCredentialID = field.NewInt(table, "dns_credential_id") c.DnsCredentialID = field.NewInt(table, "dns_credential_id")
c.ACMEUserID = field.NewInt(table, "acme_user_id")
c.KeyType = field.NewString(table, "key_type") c.KeyType = field.NewString(table, "key_type")
c.Log = field.NewString(table, "log") c.Log = field.NewString(table, "log")
@ -118,7 +129,7 @@ func (c *cert) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
} }
func (c *cert) fillFieldMap() { func (c *cert) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 15) c.fieldMap = make(map[string]field.Expr, 17)
c.fieldMap["id"] = c.ID c.fieldMap["id"] = c.ID
c.fieldMap["created_at"] = c.CreatedAt c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt c.fieldMap["updated_at"] = c.UpdatedAt
@ -131,6 +142,7 @@ func (c *cert) fillFieldMap() {
c.fieldMap["auto_cert"] = c.AutoCert c.fieldMap["auto_cert"] = c.AutoCert
c.fieldMap["challenge_method"] = c.ChallengeMethod c.fieldMap["challenge_method"] = c.ChallengeMethod
c.fieldMap["dns_credential_id"] = c.DnsCredentialID c.fieldMap["dns_credential_id"] = c.DnsCredentialID
c.fieldMap["acme_user_id"] = c.ACMEUserID
c.fieldMap["key_type"] = c.KeyType c.fieldMap["key_type"] = c.KeyType
c.fieldMap["log"] = c.Log c.fieldMap["log"] = c.Log
@ -217,6 +229,77 @@ func (a certBelongsToDnsCredentialTx) Count() int64 {
return a.tx.Count() return a.tx.Count()
} }
type certBelongsToACMEUser struct {
db *gorm.DB
field.RelationField
}
func (a certBelongsToACMEUser) Where(conds ...field.Expr) *certBelongsToACMEUser {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a certBelongsToACMEUser) WithContext(ctx context.Context) *certBelongsToACMEUser {
a.db = a.db.WithContext(ctx)
return &a
}
func (a certBelongsToACMEUser) Session(session *gorm.Session) *certBelongsToACMEUser {
a.db = a.db.Session(session)
return &a
}
func (a certBelongsToACMEUser) Model(m *model.Cert) *certBelongsToACMEUserTx {
return &certBelongsToACMEUserTx{a.db.Model(m).Association(a.Name())}
}
type certBelongsToACMEUserTx struct{ tx *gorm.Association }
func (a certBelongsToACMEUserTx) Find() (result *model.AcmeUser, err error) {
return result, a.tx.Find(&result)
}
func (a certBelongsToACMEUserTx) Append(values ...*model.AcmeUser) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a certBelongsToACMEUserTx) Replace(values ...*model.AcmeUser) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a certBelongsToACMEUserTx) Delete(values ...*model.AcmeUser) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a certBelongsToACMEUserTx) Clear() error {
return a.tx.Clear()
}
func (a certBelongsToACMEUserTx) Count() int64 {
return a.tx.Count()
}
type certDo struct{ gen.DO } type certDo struct{ gen.DO }
// FirstByID Where("id=@id") // FirstByID Where("id=@id")