feat(ldap): Active Directory 双目录支持与 Docker 构建优化
- 新增 ldap_ad.go,支持 AD 密码编码、字段映射与目录类型判断 - 重构 ldap/ldap_users/ldap_ou,兼容 OpenLDAP 与 AD 登录、导入、OU 浏览 - 前端系统设置增加目录类型选择与 AD 配置项 - Dockerfile 按 TARGETARCH 单架构编译 Agent,限制 Node 内存防 OOM - run.sh 新增 docker fast/upgrade,README 补充 LDAP/AD 与常见问题
This commit is contained in:
1 parent
0f0f2770e1
commit
78c27037e3
12 files changed
+613
-226
No files matched your search
@@ -24,7 +24,10 @@ const SETTINGS_TABS = [
|
||||
] as const;
|
||||
type SettingsSubTab = (typeof SETTINGS_TABS)[number]['id'];
|
||||
|
||||
export type LdapServerType = 'openldap' | 'ad';
|
||||
|
||||
export interface LdapFormData {
|
||||
server_type: LdapServerType;
|
||||
ldap_host: string;
|
||||
ldap_port: number;
|
||||
use_ldaps: boolean;
|
||||
@@ -32,6 +35,11 @@ export interface LdapFormData {
|
||||
admin_password: string;
|
||||
base_dn: string;
|
||||
search_filter: string;
|
||||
user_mapping: {
|
||||
username: string;
|
||||
email: string;
|
||||
display_name: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface SystemSettingsTabProps {
|
||||
@@ -325,6 +333,32 @@ export function SystemSettingsTab(props: SystemSettingsTabProps) {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs dg-text-muted">目录类型</label>
|
||||
<Select
|
||||
value={ldapForm.server_type}
|
||||
onValueChange={(v: LdapServerType) => {
|
||||
const isAD = v === 'ad';
|
||||
setLdapForm({
|
||||
...ldapForm,
|
||||
server_type: v,
|
||||
ldap_port: isAD && ldapForm.ldap_port === 389 ? 389 : ldapForm.ldap_port,
|
||||
search_filter: ldapForm.search_filter || (isAD ? '(sAMAccountName=%s)' : '(uid=%s)'),
|
||||
user_mapping: isAD
|
||||
? { username: 'sAMAccountName', email: 'mail', display_name: 'displayName' }
|
||||
: { username: 'uid', email: 'mail', display_name: 'cn' },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="dg-input">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="dg-input">
|
||||
<SelectItem value="openldap">OpenLDAP</SelectItem>
|
||||
<SelectItem value="ad">Active Directory</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs dg-text-muted">LDAP 服务器地址</label>
|
||||
<Input
|
||||
@@ -350,7 +384,7 @@ export function SystemSettingsTab(props: SystemSettingsTabProps) {
|
||||
value={ldapForm.base_dn}
|
||||
onChange={(e) => setLdapForm({ ...ldapForm, base_dn: e.target.value })}
|
||||
className="dg-input"
|
||||
placeholder="ou=users,dc=example,dc=com"
|
||||
placeholder={ldapForm.server_type === 'ad' ? 'DC=example,DC=com' : 'ou=users,dc=example,dc=com'}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
@@ -359,7 +393,7 @@ export function SystemSettingsTab(props: SystemSettingsTabProps) {
|
||||
value={ldapForm.admin_dn}
|
||||
onChange={(e) => setLdapForm({ ...ldapForm, admin_dn: e.target.value })}
|
||||
className="dg-input"
|
||||
placeholder="cn=admin,dc=example,dc=com"
|
||||
placeholder={ldapForm.server_type === 'ad' ? 'CN=admin,CN=Users,DC=example,DC=com' : 'cn=admin,dc=example,dc=com'}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
@@ -378,7 +412,43 @@ export function SystemSettingsTab(props: SystemSettingsTabProps) {
|
||||
value={ldapForm.search_filter}
|
||||
onChange={(e) => setLdapForm({ ...ldapForm, search_filter: e.target.value })}
|
||||
className="dg-input"
|
||||
placeholder="(uid=%s)"
|
||||
placeholder={ldapForm.server_type === 'ad' ? '(sAMAccountName=%s)' : '(uid=%s)'}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs dg-text-muted">用户名字段</label>
|
||||
<Input
|
||||
value={ldapForm.user_mapping.username}
|
||||
onChange={(e) => setLdapForm({
|
||||
...ldapForm,
|
||||
user_mapping: { ...ldapForm.user_mapping, username: e.target.value },
|
||||
})}
|
||||
className="dg-input"
|
||||
placeholder={ldapForm.server_type === 'ad' ? 'sAMAccountName' : 'uid'}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs dg-text-muted">邮箱字段</label>
|
||||
<Input
|
||||
value={ldapForm.user_mapping.email}
|
||||
onChange={(e) => setLdapForm({
|
||||
...ldapForm,
|
||||
user_mapping: { ...ldapForm.user_mapping, email: e.target.value },
|
||||
})}
|
||||
className="dg-input"
|
||||
placeholder="mail"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs dg-text-muted">显示名字段</label>
|
||||
<Input
|
||||
value={ldapForm.user_mapping.display_name}
|
||||
onChange={(e) => setLdapForm({
|
||||
...ldapForm,
|
||||
user_mapping: { ...ldapForm.user_mapping, display_name: e.target.value },
|
||||
})}
|
||||
className="dg-input"
|
||||
placeholder={ldapForm.server_type === 'ad' ? 'displayName' : 'cn'}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 col-span-2">
|
||||
@@ -388,6 +458,9 @@ export function SystemSettingsTab(props: SystemSettingsTabProps) {
|
||||
className="data-[state=checked]:bg-blue-600"
|
||||
/>
|
||||
<span className="text-sm text-[var(--dg-text-secondary)]">启用 LDAPS(SSL 加密)</span>
|
||||
{ldapForm.server_type === 'ad' && (
|
||||
<span className="text-xs dg-text-muted">AD 创建用户必须启用 LDAPS</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user