feat(X-Pack): Add LDAP authentication mechanism

This commit is contained in:
fit2cloud-chenyw
2025-12-01 14:06:51 +08:00
committed by fit2cloud-chenyw
parent dcceb1e55d
commit a77f1842be
11 changed files with 448 additions and 103 deletions
@@ -0,0 +1,5 @@
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon_qr_outlined">
<path id="&#229;&#189;&#162;&#231;&#138;&#182;" d="M3.875 8.625H9.125V3.375H3.875V8.625ZM3.125 1.875H9.875C10.2892 1.875 10.625 2.21079 10.625 2.625V9.375C10.625 9.78921 10.2892 10.125 9.875 10.125H3.125C2.71079 10.125 2.375 9.78921 2.375 9.375V2.625C2.375 2.21079 2.71079 1.875 3.125 1.875ZM5.375 4.875H7.625V7.125H5.375V4.875ZM3.875 12.75V14.625H5.75V12.75H3.875ZM3.125 11.25H6.5C6.91421 11.25 7.25 11.5858 7.25 12V15.375C7.25 15.7892 6.91421 16.125 6.5 16.125H3.125C2.71079 16.125 2.375 15.7892 2.375 15.375V12C2.375 11.5858 2.71079 11.25 3.125 11.25ZM13.25 3.375V5.25H15.125V3.375H13.25ZM12.5 1.875H15.875C16.2892 1.875 16.625 2.21079 16.625 2.625V6C16.625 6.41421 16.2892 6.75 15.875 6.75H12.5C12.0858 6.75 11.75 6.41421 11.75 6V2.625C11.75 2.21079 12.0858 1.875 12.5 1.875ZM13.25 12.75V14.625H15.125V12.75H13.25ZM12.5 11.25H15.875C16.2892 11.25 16.625 11.5858 16.625 12V15.375C16.625 15.7892 16.2892 16.125 15.875 16.125H12.5C12.0858 16.125 11.75 15.7892 11.75 15.375V12C11.75 11.5858 12.0858 11.25 12.5 11.25ZM8.75 11.25H10.25V12.75H8.75V11.25ZM8.75 13.875H10.25V16.125H8.75V13.875ZM11.75 8.25H13.25V9.75H11.75V8.25ZM14.375 8.25H16.625V9.75H14.375V8.25Z" fill="#1F2329"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+2 -2
View File
@@ -1,4 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="32" height="32" viewBox="0 0 32 32" fill="" xmlns="http://www.w3.org/2000/svg">
<g id="logo_cas">
<g id="logo_cas_2">
<mask id="mask0_3028_68898" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="1" y="1" width="30" height="30">
@@ -6,7 +6,7 @@
</mask>
<g mask="url(#mask0_3028_68898)">
<g id="CAS">
<path d="M3.03105 12.86H4.11105V19.07H8.04106V20H3.03105V12.86ZM8.93926 12.86H11.5393C12.6893 12.86 13.5593 13.18 14.1593 13.83C14.7193 14.43 14.9993 15.3 14.9993 16.43C14.9993 17.55 14.7093 18.42 14.1393 19.04C13.5393 19.68 12.6693 20 11.5193 20H8.93926V12.86ZM10.0293 13.79V19.07H11.3193C12.2193 19.07 12.8893 18.85 13.3093 18.42C13.7193 17.99 13.9293 17.33 13.9293 16.43C13.9293 15.51 13.7193 14.85 13.3193 14.43C12.8993 14 12.2393 13.79 11.3393 13.79H10.0293ZM18.1572 12.86H19.3972L22.1472 20H20.9772L20.3072 18.16H17.2372L16.5672 20H15.4072L18.1572 12.86ZM17.5672 17.26H19.9772L18.7972 14.03H18.7572L17.5672 17.26ZM22.8455 12.86H25.8055C27.5055 12.86 28.3555 13.58 28.3555 15.03C28.3555 16.49 27.4955 17.22 25.7855 17.22H23.9355V20H22.8455V12.86ZM23.9355 13.79V16.29H25.7155C26.2555 16.29 26.6455 16.19 26.8955 15.99C27.1355 15.79 27.2655 15.47 27.2655 15.03C27.2655 14.59 27.1355 14.27 26.8855 14.09C26.6355 13.89 26.2455 13.79 25.7155 13.79H23.9355Z" fill="#3370FF"/>
<path d="M3.03105 12.86H4.11105V19.07H8.04106V20H3.03105V12.86ZM8.93926 12.86H11.5393C12.6893 12.86 13.5593 13.18 14.1593 13.83C14.7193 14.43 14.9993 15.3 14.9993 16.43C14.9993 17.55 14.7093 18.42 14.1393 19.04C13.5393 19.68 12.6693 20 11.5193 20H8.93926V12.86ZM10.0293 13.79V19.07H11.3193C12.2193 19.07 12.8893 18.85 13.3093 18.42C13.7193 17.99 13.9293 17.33 13.9293 16.43C13.9293 15.51 13.7193 14.85 13.3193 14.43C12.8993 14 12.2393 13.79 11.3393 13.79H10.0293ZM18.1572 12.86H19.3972L22.1472 20H20.9772L20.3072 18.16H17.2372L16.5672 20H15.4072L18.1572 12.86ZM17.5672 17.26H19.9772L18.7972 14.03H18.7572L17.5672 17.26ZM22.8455 12.86H25.8055C27.5055 12.86 28.3555 13.58 28.3555 15.03C28.3555 16.49 27.4955 17.22 25.7855 17.22H23.9355V20H22.8455V12.86ZM23.9355 13.79V16.29H25.7155C26.2555 16.29 26.6455 16.19 26.8955 15.99C27.1355 15.79 27.2655 15.47 27.2655 15.03C27.2655 14.59 27.1355 14.27 26.8855 14.09C26.6355 13.89 26.2455 13.79 25.7155 13.79H23.9355Z" fill=""/>
</g>
</g>
</g>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

+12 -1
View File
@@ -752,7 +752,18 @@
"oidc_settings": "OIDC Settings",
"metadata_url": "Metadata URL",
"realm": "Realm",
"oidc_field_mapping_placeholder": "e.g., {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}"
"oidc_field_mapping_placeholder": "e.g., {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}",
"ldap_settings": "LDAP Settings",
"server_address": "Server Address",
"server_address_placeholder": "Example: ldap://ldap.example.com:389",
"bind_dn": "Bind DN",
"bind_dn_placeholder": "Example: cn=admin,dc=example,dc=com",
"bind_pwd": "Bind Password",
"ou": "User OU",
"ou_placeholder": "Example: ou=users,dc=example,dc=com",
"user_filter": "User Filter",
"user_filter_placeholder": "Example: uid",
"ldap_field_mapping_placeholder": "Example: {\"account\": \"ldapAccount\", \"name\": \"ldapName\", \"email\": \"mail\"}"
},
"login": {
"default_login": "Default",
+12 -1
View File
@@ -752,7 +752,18 @@
"oidc_settings": "OIDC 설정",
"metadata_url": "메타데이터 URL",
"realm": "영역",
"oidc_field_mapping_placeholder": "예: {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}"
"oidc_field_mapping_placeholder": "예: {\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"}",
"ldap_settings": "LDAP 설정",
"server_address": "서버 주소",
"server_address_placeholder": "예: ldap://ldap.example.com:389",
"bind_dn": "바인드 DN",
"bind_dn_placeholder": "예: cn=admin,dc=example,dc=com",
"bind_pwd": "바인드 비밀번호",
"ou": "사용자 OU",
"ou_placeholder": "예: ou=users,dc=example,dc=com",
"user_filter": "사용자 필터",
"user_filter_placeholder": "예: uid",
"ldap_field_mapping_placeholder": "예: {\"account\": \"ldapAccount\", \"name\": \"ldapName\", \"email\": \"mail\"}"
},
"login": {
"default_login": "기본값",
+12 -1
View File
@@ -752,7 +752,18 @@
"oidc_settings": "OIDC 设置",
"metadata_url": "元数据地址",
"realm": "领域",
"oidc_field_mapping_placeholder": "例如:{'{'}\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"{'}'}"
"oidc_field_mapping_placeholder": "例如:{'{'}\"account\": \"oidcAccount\", \"name\": \"oidcName\", \"email\": \"email\"{'}'}",
"ldap_settings": "LDAP 设置",
"server_address": "服务器地址",
"server_address_placeholder": "例如:ldap://ldap.example.com:389",
"bind_dn": "绑定 DN",
"bind_dn_placeholder": "例如:cn=admin,dc=example,dc=com",
"bind_pwd": "绑定密码",
"ou": "用户 OU",
"ou_placeholder": "例如:ou=users,dc=example,dc=com",
"user_filter": "用户过滤器",
"user_filter_placeholder": "例如:uid",
"ldap_field_mapping_placeholder": "例如:{'{'}\"account\": \"ldapAccount\", \"name\": \"ldapName\", \"email\": \"mail\"{'}'}"
},
"login": {
"default_login": "默认",
+40 -32
View File
@@ -28,42 +28,45 @@
</div>
<div v-else class="welcome" style="height: 0"></div>
<div class="login-form">
<h2 class="title">{{ $t('common.login') }}</h2>
<el-form
ref="loginFormRef"
class="form-content_error"
:model="loginForm"
:rules="rules"
@keyup.enter="submitForm"
>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
clearable
:placeholder="$t('common.your_account_email_address')"
size="large"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:placeholder="$t('common.enter_your_password')"
type="password"
show-password
clearable
size="large"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" class="login-btn" @click="submitForm">{{
$t('common.login_')
}}</el-button>
</el-form-item>
</el-form>
<div class="default-login-tabs">
<h2 class="title">{{ $t('common.login') }}</h2>
<el-form
ref="loginFormRef"
class="form-content_error"
:model="loginForm"
:rules="rules"
@keyup.enter="submitForm"
>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
clearable
:placeholder="$t('common.your_account_email_address')"
size="large"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:placeholder="$t('common.enter_your_password')"
type="password"
show-password
clearable
size="large"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" class="login-btn" @click="submitForm">{{
$t('common.login_')
}}</el-button>
</el-form-item>
</el-form>
</div>
<Handler
ref="xpackLoginHandler"
v-model:loading="showLoading"
jsname="L2NvbXBvbmVudC9sb2dpbi9IYW5kbGVy"
@switch-tab="switchTab"
/>
</div>
</div>
@@ -93,7 +96,9 @@ const loginForm = ref({
username: '',
password: '',
})
const activeName = ref('simple')
// const isLdap = computed(() => activeName.value == 'ldap')
const bg = computed(() => {
return appearanceStore.getBg || (appearanceStore.isBlue ? loginImage : login_image)
})
@@ -118,6 +123,9 @@ const submitForm = () => {
}
})
}
const switchTab = (name: string) => {
activeName.value = name || 'simple'
}
</script>
<style lang="less" scoped>
+11 -6
View File
@@ -8,18 +8,19 @@
:larksuite="loginCategory.larksuite"
/>
</div> -->
<LdapLoginForm v-if="isLdap" />
<el-divider v-if="anyEnable" class="de-other-login-divider">{{
t('login.other_login')
}}</el-divider>
<el-form-item v-if="anyEnable" class="other-login-item">
<div class="login-list">
<!-- <QrcodeLdap
<QrcodeLdap
v-if="loginCategory.qrcode || loginCategory.ldap"
ref="qrcodeLdapHandler"
:qrcode="loginCategory.qrcode"
:ldap="loginCategory.ldap"
@status-change="qrStatusChange"
/> -->
/>
<Oidc v-if="loginCategory.oidc" @switch-category="switcherCategory" />
<Oauth2 v-if="loginCategory.oauth2" ref="oauth2Handler" @switch-category="switcherCategory" />
<Cas v-if="loginCategory.cas" @switch-category="switcherCategory" />
@@ -51,8 +52,9 @@
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
/* import QrcodeLdap from './QrcodeLdap.vue'
import Oidc from './Oidc.vue'
import QrcodeLdap from './QrcodeLdap.vue'
import LdapLoginForm from './LdapLoginForm.vue'
/* import Oidc from './Oidc.vue'
import Oauth2 from './Oauth2.vue'
import Saml2 from './Saml2.vue' */
import Oidc from './Oidc.vue'
@@ -70,6 +72,7 @@ import { loadClient, type LoginCategory } from './PlatformClient'
// import { logoutHandler } from '@/utils/logout'
import { useI18n } from 'vue-i18n'
// import PlatformError from './PlatformError.vue'
const isLdap = ref(false)
defineProps<{
loading: boolean
}>()
@@ -211,14 +214,16 @@ const init = (cb?: () => void) => {
})
}
/* const qrStatusChange = (activeComponent: string) => {
const qrStatusChange = (activeComponent: string) => {
qrStatus.value = activeComponent === 'qrcode'
isLdap.value = false
if (activeComponent === 'account') {
emits('switchTab', 'simple')
} else if (activeComponent === 'ldap') {
isLdap.value = true
switcherCategory({ category: 'ldap', proxy: '' })
}
} */
}
/* const showMfa = ref(false)
const toMfa = (mfa) => {
state.mfaData = mfa
@@ -0,0 +1,99 @@
<template>
<div class="default-login-tabs-ldap">
<h2 class="title">{{ t('login.ldap_login') }}</h2>
<el-form
ref="loginFormRef"
class="form-content_error"
:model="loginForm"
@keyup.enter="submitForm"
>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
clearable
:placeholder="t('login.input_account')"
size="large"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:placeholder="$t('common.enter_your_password')"
type="password"
show-password
clearable
size="large"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" class="login-btn" @click="submitForm">{{
$t('common.login_')
}}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { request } from '@/utils/request'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user.ts'
const userStore = useUserStore()
const router = useRouter()
const { t } = useI18n()
const loginForm = ref({
username: '',
password: '',
origin: 1,
})
const loginFormRef = ref()
const submitForm = () => {
loginFormRef.value.validate((valid: boolean) => {
if (valid) {
const data = { ...loginForm.value }
request.post('/system/authentication/sso/3', data).then((res: any) => {
const token = res.access_token
userStore.setToken(token)
userStore.setExp(res.exp)
userStore.setTime(Date.now())
router.push('/')
})
}
})
}
</script>
<style lang="less" scoped>
.form-content_error {
.ed-form-item--default {
margin-bottom: 24px;
&.is-error {
margin-bottom: 48px;
}
}
}
.title {
font-weight: 500;
font-style: Medium;
font-size: 20px;
line-height: 28px;
margin-bottom: 24px;
}
.login-btn {
width: 100%;
height: 45px;
font-size: 16px;
border-radius: 4px;
}
.agreement {
margin-top: 20px;
text-align: center;
color: #666;
}
</style>
@@ -0,0 +1,185 @@
<template>
<div
v-for="(item, index) in validComponentList"
:key="item.key"
class="item"
:class="{ qrcode: item.key !== 'ldap' }"
@click="execute(item, index)"
>
<el-icon>
<Icon>
<component :is="item.icon" class="svg-icon"></component>
</Icon>
</el-icon>
<span class="name">
{{ item.title }}
</span>
</div>
</template>
<script lang="ts" setup>
import { Icon } from '@/components/icon-custom'
import icon_qr_outlined from '@/assets/svg/icon_qr_outlined.svg'
import logo_ldap from '@/assets/svg/logo_ldap.svg'
import icon_pc_outlined from '@/assets/svg/icon_pc_outlined.svg'
import { onMounted, ref } from 'vue'
import { propTypes } from '@/utils/propTypes'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const props = defineProps({
qrcode: propTypes.bool.def(false),
ldap: propTypes.bool.def(false),
})
interface OptionItem {
key: string
icon: string
title: string
}
const componentList = ref<OptionItem[]>([
{
key: 'qrcode',
icon: icon_qr_outlined,
title: t('login.qr_code'),
},
{
key: 'ldap',
icon: logo_ldap,
title: 'LDAP',
},
{
key: 'account',
icon: icon_pc_outlined,
title: t('user.account'),
},
])
const componentMap = ref({}) as any
const validComponentList = ref<OptionItem[]>([])
const activeComponent = ref<string>('account')
const initActiveComponent = () => {
validComponentList.value = []
componentList.value.forEach((item) => {
if (item.key !== activeComponent.value && getPropsItem(item.key)) {
validComponentList.value.push(item)
}
})
}
const getPropsItem = (key: string): boolean => {
if (key === 'qrcode') {
return props.qrcode
}
if (key === 'ldap') {
return props.ldap
}
return false
}
const formatOptionMap = () => {
componentMap.value['qrcode'] = componentList.value[0]
componentMap.value['ldap'] = componentList.value[1]
componentMap.value['account'] = componentList.value[2]
}
const emits = defineEmits(['status-change'])
const execute = (item: OptionItem, index: number) => {
validComponentList.value[index] = componentMap.value[activeComponent.value]
activeComponent.value = item.key
if (activeComponent.value === 'account') {
showDefaultTabs()
} else {
hiddenDefaultTabs()
}
emits('status-change', activeComponent.value)
}
const hiddenDefaultTabs = () => {
const dom = document.getElementsByClassName('default-login-tabs') as any
const len = dom?.length || 0
if (len) {
dom[0]['style']['display'] = 'none'
if (len > 1) {
dom[1]['style']['display'] = 'none'
if (len > 2 && dom[2]) {
dom[2]['style']['display'] = 'none'
}
}
}
}
const showDefaultTabs = () => {
const dom = document.getElementsByClassName('default-login-tabs') as any
const len = dom?.length || 0
if (len) {
dom[0]['style']['display'] = ''
if (len > 1) {
dom[1]['style']['display'] = ''
if (len > 2 && dom[2]) {
dom[2]['style']['display'] = ''
}
}
}
}
const setActive = (active?: string) => {
const curActive = active || 'account'
let index = -1
let item: OptionItem = {
key: 'account',
icon: 'icon_pc_outlined',
title: t('user.account'),
}
for (let i = 0; i < validComponentList.value.length; i++) {
const element = validComponentList.value[i]
if (element.key === curActive) {
item = element
index = i
}
}
validComponentList.value[index] = componentMap.value[activeComponent.value]
activeComponent.value = item.key
}
defineExpose({
setActive,
})
onMounted(() => {
formatOptionMap()
initActiveComponent()
})
</script>
<style lang="less" scoped>
.item {
width: 32px;
cursor: pointer;
&.qrcode,
&.account {
.ed-icon {
padding: 5px;
}
}
.ed-icon {
font-size: 32px;
border: 1px solid #dee0e3;
border-radius: 50%;
color: var(--ed-color-primary);
}
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-between;
.name {
margin-top: 8px;
color: #000;
text-align: center;
font-family: var(--ed-color-primary, 'PingFang');
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 166.667% */
display: none;
}
}
</style>
@@ -7,23 +7,16 @@ import { request } from '@/utils/request'
const { t } = useI18n()
const dialogVisible = ref(false)
const loadingInstance = ref<ReturnType<typeof ElLoading.service> | null>(null)
const mappingTips = ref(t('system.for_example'))
const ldapForm = ref<FormInstance>()
interface LdapForm {
addr?: string
dn?: string
pwd?: string
ou?: string
filter?: string
mapping?: string
}
const id = ref<number | null>(null)
const state = reactive({
form: reactive<LdapForm>({
addr: '',
dn: '',
pwd: '',
form: reactive<any>({
server_address: '',
bind_dn: '',
bind_pwd: '',
ou: '',
filter: '',
user_filter: '',
mapping: '',
}),
})
@@ -35,13 +28,14 @@ const validateMapping = (rule, value, callback) => {
}
try {
JSON.parse(value)
} catch (e) {
callback(new Error(t('system.in_json_format')))
} catch (e: any) {
console.error(e)
callback(new Error(t('authentication.in_json_format')))
}
callback()
}
const rule = reactive<FormRules>({
addr: [
server_address: [
{
required: true,
message: t('common.require'),
@@ -54,14 +48,14 @@ const rule = reactive<FormRules>({
trigger: 'blur',
},
],
dn: [
bind_dn: [
{
required: true,
message: t('common.require'),
trigger: ['blur', 'change'],
},
],
pwd: [
bind_pwd: [
{
required: true,
message: t('common.require'),
@@ -75,7 +69,7 @@ const rule = reactive<FormRules>({
trigger: ['blur', 'change'],
},
],
filter: [
user_filter: [
{
required: true,
message: t('common.require'),
@@ -84,26 +78,27 @@ const rule = reactive<FormRules>({
],
mapping: [
{
required: true,
required: false,
message: t('common.require'),
trigger: ['blur', 'change'],
},
{ required: true, validator: validateMapping, trigger: 'blur' },
{ required: false, validator: validateMapping, trigger: 'blur' },
],
})
const edit = () => {
showLoading()
request
.get('/setting/authentication/info/ldap')
.get('/system/authentication/3')
.then((res) => {
const resData = res as Partial<LdapForm>
;(Object.keys(resData) as (keyof LdapForm)[]).forEach((key) => {
const value = resData[key]
if (value !== undefined) {
state.form[key] = value as any
}
})
if (!res?.config) {
return
}
id.value = res.id
const data = JSON.parse(res.config)
for (const key in data) {
state.form[key] = data[key] as any
}
})
.finally(() => {
closeLoading()
@@ -117,7 +112,15 @@ const submitForm = async (formEl: FormInstance | undefined) => {
await formEl.validate((valid) => {
if (valid) {
const param = { ...state.form }
const method = request.post('/setting/authentication/save/ldap', param)
const data = {
id: 3,
type: 3,
config: JSON.stringify(param),
name: 'ldap',
}
const method = id.value
? request.put('/system/authentication', data)
: request.post('/system/authentication', data)
showLoading()
method
.then((res) => {
@@ -138,6 +141,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
id.value = null
dialogVisible.value = false
}
@@ -155,16 +159,21 @@ const closeLoading = () => {
}
const validate = () => {
const url = '/setting/authentication/validate/ldap'
const data = state.form
const url = '/system/authentication/status'
const config_data = state.form
const data = {
type: 3,
name: 'ldap',
config: JSON.stringify(config_data),
}
showLoading()
request
.post(url, data)
.patch(url, data)
.then((res) => {
if (res === 'true') {
ElMessage.success(t('commons.test_connect') + t('report.last_status_success'))
if (res) {
ElMessage.success(t('ds.connection_success'))
} else {
ElMessage.error(t('commons.test_connect') + t('report.last_status_fail') + ': ' + res.data)
ElMessage.error(t('ds.connection_failed'))
}
})
.finally(() => {
@@ -181,7 +190,7 @@ defineExpose({
<template>
<el-drawer
v-model="dialogVisible"
:title="t('system.ldap_settings')"
:title="t('authentication.ldap_settings')"
modal-class="platform-info-drawer"
size="600px"
direction="rtl"
@@ -194,52 +203,55 @@ defineExpose({
label-width="80px"
label-position="top"
>
<el-form-item :label="t('system.ldap_address')" prop="addr">
<el-form-item :label="t('authentication.server_address')" prop="addr">
<el-input
v-model="state.form.addr"
:placeholder="t('common.please_input') + t('system.such_as_ldap')"
:placeholder="t('authentication.server_address_placeholder')"
/>
</el-form-item>
<el-form-item :label="t('system.bind_dn')" prop="dn">
<el-input v-model="state.form.dn" :placeholder="t('common.please_input') + 'DN'" />
<el-form-item :label="t('authentication.bind_dn')" prop="bind_dn">
<el-input
v-model="state.form.bind_dn"
:placeholder="t('authentication.bind_dn_placeholder')"
/>
</el-form-item>
<el-form-item :label="t('common.pwd')" prop="pwd">
<el-form-item :label="t('authentication.bind_pwd')" prop="bind_pwd">
<el-input
v-model="state.form.pwd"
v-model="state.form.bind_pwd"
type="password"
show-password
:placeholder="t('common.please_input') + t('common.pwd')"
:placeholder="t('common.please_input')"
/>
</el-form-item>
<el-form-item :label="t('system.user_ou')" prop="ou">
<el-form-item :label="t('authentication.ou')" prop="ou">
<el-input v-model="state.form.ou" :placeholder="t('authentication.ou_placeholder')" />
</el-form-item>
<el-form-item :label="t('authentication.user_filter')" prop="user_filter">
<el-input
v-model="state.form.ou"
:placeholder="t('common.please_input') + t('system.separate_each_ou')"
v-model="state.form.user_filter"
:placeholder="t('authentication.user_filter_placeholder')"
/>
</el-form-item>
<el-form-item :label="t('system.user_filter')" prop="filter">
<el-form-item :label="t('authentication.field_mapping')" prop="mapping">
<el-input
v-model="state.form.filter"
:placeholder="t('common.please_input') + t('system.such_as_uid')"
v-model="state.form.mapping"
:placeholder="t('authentication.ldap_field_mapping_placeholder')"
/>
</el-form-item>
<el-form-item :label="t('system.ldap_attribute_mapping')" prop="mapping">
<el-input v-model="state.form.mapping" :placeholder="mappingTips" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button secondary @click="resetForm(ldapForm)">{{ t('common.cancel') }}</el-button>
<el-button secondary :disabled="!state.form.addr" @click="validate">
{{ t('commons.test_connect') }}
{{ t('ds.test_connection') }}
</el-button>
<el-button type="primary" @click="submitForm(ldapForm)">
{{ t('commons.save') }}
{{ t('common.save') }}
</el-button>
</span>
</template>
@@ -90,9 +90,7 @@ const init = (needLoading: boolean) => {
.get(url)
.then((res) => {
if (res) {
infos.value = [...(res as CardInfo[])].filter(
(item) => item.name === 'cas' || item.name === 'oauth2' || item.name === 'oidc'
)
infos.value = [...(res as CardInfo[])].filter((item) => item.name !== 'saml2')
showInfos.value = [...infos.value]
}
loading.value = false