mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 09:17:06 +08:00
feat(X-Pack): Add LDAP authentication mechanism
This commit is contained in:
committed by
fit2cloud-chenyw
parent
dcceb1e55d
commit
a77f1842be
@@ -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="形状" 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 |
@@ -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 |
@@ -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",
|
||||
|
||||
@@ -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": "기본값",
|
||||
|
||||
@@ -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": "默认",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user