feat: 远程数据库增加是否开启 CA 验证选项 (#3232)

pull/3249/head
ssongliu 2023-12-08 17:26:07 +08:00 committed by GitHub
parent d4def44545
commit 3f8abf8ad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 27 additions and 12 deletions

View File

@ -149,8 +149,10 @@ func ConnWithSSL(ssl, skipVerify bool, clientKey, clientCert, rootCert string) (
return "", nil return "", nil
} }
pool := x509.NewCertPool() pool := x509.NewCertPool()
if ok := pool.AppendCertsFromPEM([]byte(rootCert)); !ok { if len(rootCert) != 0 {
return "", errors.New("unable to append root cert to pool") if ok := pool.AppendCertsFromPEM([]byte(rootCert)); !ok {
return "", errors.New("unable to append root cert to pool")
}
} }
cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey)) cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
if err != nil { if err != nil {

View File

@ -215,6 +215,7 @@ export namespace Database {
password: string; password: string;
ssl: boolean; ssl: boolean;
hasCA: boolean;
rootCert: string; rootCert: string;
clientKey: string; clientKey: string;
clientCert: string; clientCert: string;

View File

@ -396,6 +396,7 @@ const message = {
clientKey: 'Client Private Key', clientKey: 'Client Private Key',
clientCert: 'Client Certificate', clientCert: 'Client Certificate',
caCert: 'CA Certificate', caCert: 'CA Certificate',
hasCA: 'Has CA Certificate',
skipVerify: 'Ignore Certificate Validity Check', skipVerify: 'Ignore Certificate Validity Check',
formatHelper: formatHelper:

View File

@ -388,6 +388,7 @@ const message = {
clientKey: '', clientKey: '',
clientCert: '', clientCert: '',
caCert: 'CA ', caCert: 'CA ',
hasCA: ' CA ',
skipVerify: '', skipVerify: '',
formatHelper: ' {0}', formatHelper: ' {0}',

View File

@ -387,6 +387,7 @@ const message = {
ssl: '使 SSL', ssl: '使 SSL',
clientKey: '', clientKey: '',
clientCert: '', clientCert: '',
hasCA: ' CA ',
caCert: 'CA ', caCert: 'CA ',
skipVerify: '', skipVerify: '',

View File

@ -184,9 +184,9 @@
{{ $t('container.autoRemove') }} {{ $t('container.autoRemove') }}
</el-checkbox> </el-checkbox>
</el-form-item> </el-form-item>
<el-form-item :label="$t('container.privileged')"> <el-form-item>
<el-checkbox v-model="dialogData.rowData!.privileged"> <el-checkbox v-model="dialogData.rowData!.privileged">
{{ $t('commons.button.start') }} {{ $t('container.privileged') }}
</el-checkbox> </el-checkbox>
<span class="input-help">{{ $t('container.privilegedHelper') }}</span> <span class="input-help">{{ $t('container.privilegedHelper') }}</span>
</el-form-item> </el-form-item>

View File

@ -62,6 +62,20 @@
/> />
</el-form-item> </el-form-item>
<div v-if="dialogData.rowData!.ssl"> <div v-if="dialogData.rowData!.ssl">
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.hasCA"
:label="$t('database.hasCA')"
/>
</el-form-item>
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.skipVerify"
:label="$t('database.skipVerify')"
/>
</el-form-item>
<el-form-item :label="$t('database.clientKey')" prop="clientKey"> <el-form-item :label="$t('database.clientKey')" prop="clientKey">
<el-input <el-input
type="textarea" type="textarea"
@ -78,7 +92,7 @@
v-model="dialogData.rowData!.clientCert" v-model="dialogData.rowData!.clientCert"
/> />
</el-form-item> </el-form-item>
<el-form-item :label="$t('database.caCert')" prop="rootCert"> <el-form-item v-if="dialogData.rowData!.hasCA" :label="$t('database.caCert')" prop="rootCert">
<el-input <el-input
type="textarea" type="textarea"
@change="isOK = false" @change="isOK = false"
@ -86,13 +100,6 @@
v-model="dialogData.rowData!.rootCert" v-model="dialogData.rowData!.rootCert"
/> />
</el-form-item> </el-form-item>
<el-form-item>
<el-checkbox
@change="isOK = false"
v-model="dialogData.rowData!.skipVerify"
:label="$t('database.skipVerify')"
/>
</el-form-item>
</div> </div>
<el-form-item :label="$t('commons.table.description')" prop="description"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" /> <el-input clearable v-model.trim="dialogData.rowData!.description" />
@ -151,6 +158,7 @@ const acceptParams = (params: DialogProps): void => {
if (dialogData.value.rowData.version.startsWith('10.')) { if (dialogData.value.rowData.version.startsWith('10.')) {
dialogData.value.rowData.version = '10.x'; dialogData.value.rowData.version = '10.x';
} }
dialogData.value.rowData.hasCA = dialogData.value.rowData.rootCert?.length === 0;
title.value = i18n.global.t('database.' + dialogData.value.title + 'RemoteDB'); title.value = i18n.global.t('database.' + dialogData.value.title + 'RemoteDB');
drawerVisible.value = true; drawerVisible.value = true;
}; };
@ -188,6 +196,7 @@ const onSubmit = async (formEl: FormInstance | undefined, operation: string) =>
if (!valid) return; if (!valid) return;
dialogData.value.rowData.from = 'remote'; dialogData.value.rowData.from = 'remote';
loading.value = true; loading.value = true;
dialogData.value.rowData.rootCert = dialogData.value.rowData.hasCA ? dialogData.value.rowData.rootCert : '';
if (operation === 'check') { if (operation === 'check') {
await checkDatabase(dialogData.value.rowData) await checkDatabase(dialogData.value.rowData)
.then((res) => { .then((res) => {