mirror of https://github.com/openspug/spug
add ladp config
parent
b6463e958d
commit
2eb55e0879
|
@ -201,7 +201,7 @@ def login(request):
|
||||||
if not config:
|
if not config:
|
||||||
return handle_response(error='请在系统设置中配置LDAP后再尝试通过该方式登录')
|
return handle_response(error='请在系统设置中配置LDAP后再尝试通过该方式登录')
|
||||||
ldap = LDAP(**config)
|
ldap = LDAP(**config)
|
||||||
is_success, message = ldap.valid_user(form.username, form.password)
|
is_success, message = ldap.verify_user(form.username, form.password)
|
||||||
if is_success:
|
if is_success:
|
||||||
if not user:
|
if not user:
|
||||||
user = User.objects.create(username=form.username, nickname=form.username, type=form.type)
|
user = User.objects.create(username=form.username, nickname=form.username, type=form.type)
|
||||||
|
|
|
@ -9,7 +9,9 @@ from apps.setting.user import UserSettingView
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', SettingView.as_view()),
|
url(r'^$', SettingView.as_view()),
|
||||||
url(r'^user/$', UserSettingView.as_view()),
|
url(r'^user/$', UserSettingView.as_view()),
|
||||||
|
url(r'^ldap/$', LDAPUserView.as_view()),
|
||||||
url(r'^ldap_test/$', ldap_test),
|
url(r'^ldap_test/$', ldap_test),
|
||||||
|
url(r'^ldap_import/$', ldap_import),
|
||||||
url(r'^email_test/$', email_test),
|
url(r'^email_test/$', email_test),
|
||||||
url(r'^mfa/$', MFAView.as_view()),
|
url(r'^mfa/$', MFAView.as_view()),
|
||||||
url(r'^about/$', get_about)
|
url(r'^about/$', get_about)
|
||||||
|
|
|
@ -6,14 +6,16 @@ from django.core.cache import cache
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from libs import JsonParser, Argument, json_response, auth
|
from libs import JsonParser, Argument, json_response, auth
|
||||||
from libs.utils import generate_random_str
|
from libs.utils import generate_random_str
|
||||||
|
from libs.ldap import LDAP
|
||||||
from libs.mail import Mail
|
from libs.mail import Mail
|
||||||
from libs.spug import send_login_wx_code
|
from libs.spug import send_login_wx_code
|
||||||
from libs.mixins import AdminView
|
from libs.mixins import AdminView
|
||||||
from apps.setting.utils import AppSetting
|
from apps.setting.utils import AppSetting
|
||||||
from apps.setting.models import Setting, KEYS_DEFAULT
|
from apps.setting.models import Setting, KEYS_DEFAULT
|
||||||
|
from apps.account.models import User
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
import platform
|
import platform
|
||||||
import ldap
|
import json
|
||||||
|
|
||||||
|
|
||||||
class SettingView(AdminView):
|
class SettingView(AdminView):
|
||||||
|
@ -68,18 +70,76 @@ class MFAView(AdminView):
|
||||||
def ldap_test(request):
|
def ldap_test(request):
|
||||||
form, error = JsonParser(
|
form, error = JsonParser(
|
||||||
Argument('server'),
|
Argument('server'),
|
||||||
Argument('port', type=int),
|
|
||||||
Argument('admin_dn'),
|
Argument('admin_dn'),
|
||||||
Argument('password'),
|
Argument('admin_password'),
|
||||||
|
Argument('user_ou'),
|
||||||
|
Argument('user_filter'),
|
||||||
|
Argument('map_username'),
|
||||||
|
Argument('map_nickname'),
|
||||||
|
).parse(request.body)
|
||||||
|
print('form', form)
|
||||||
|
if error is None:
|
||||||
|
ldap = LDAP(form.server, form.admin_dn, form.admin_password, form.user_ou, form.user_filter, form.map_username, form.map_nickname)
|
||||||
|
status, ret = ldap.all_user()
|
||||||
|
if status:
|
||||||
|
return json_response(ret)
|
||||||
|
return json_response(error=ret)
|
||||||
|
return json_response(error=error)
|
||||||
|
|
||||||
|
|
||||||
|
@auth('admin')
|
||||||
|
def ldap_import(request):
|
||||||
|
form, error = JsonParser(
|
||||||
|
Argument('ldap_data', type=list),
|
||||||
|
Argument('username'),
|
||||||
|
Argument('nickname'),
|
||||||
).parse(request.body)
|
).parse(request.body)
|
||||||
if error is None:
|
if error is None:
|
||||||
try:
|
for x in form.ldap_data:
|
||||||
con = ldap.initialize("ldap://{0}:{1}".format(form.server, form.port), bytes_mode=False)
|
User.objects.update_or_create(
|
||||||
con.simple_bind_s(form.admin_dn, form.password)
|
username=x[form.username],
|
||||||
|
defaults={'nickname': x[form.nickname], 'type': 'ldap'}
|
||||||
|
)
|
||||||
return json_response()
|
return json_response()
|
||||||
except Exception as e:
|
return json_response(error=error)
|
||||||
error = eval(str(e))
|
|
||||||
return json_response(error=error['desc'])
|
|
||||||
|
class LDAPUserView(AdminView):
|
||||||
|
def get(self, request):
|
||||||
|
ldap_config = AppSetting.get('ldap_service')
|
||||||
|
if not ldap_config:
|
||||||
|
return json_response(error='LDAP服务未配置')
|
||||||
|
ldap = LDAP(**ldap_config)
|
||||||
|
status, ret = ldap.all_user()
|
||||||
|
if status:
|
||||||
|
cn_key, sn_key = ldap_config.get('map_username'), ldap_config.get('map_nickname')
|
||||||
|
system_users = [x.username for x in User.objects.filter(type='ldap', deleted_by_id__isnull=True)]
|
||||||
|
for index, u in enumerate(ret):
|
||||||
|
u['cn'] = u[cn_key]
|
||||||
|
u['sn'] = u[sn_key]
|
||||||
|
u['is_exist'] = u.get(cn_key) in system_users
|
||||||
|
u['id'] = index
|
||||||
|
return json_response(ret)
|
||||||
|
return json_response(error=ret)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
form, error = JsonParser(
|
||||||
|
Argument('server'),
|
||||||
|
Argument('admin_dn'),
|
||||||
|
Argument('admin_password'),
|
||||||
|
Argument('user_ou'),
|
||||||
|
Argument('user_filter'),
|
||||||
|
Argument('map_username'),
|
||||||
|
Argument('map_nickname'),
|
||||||
|
Argument('ldap_user', help='LDAP用户不能为空'),
|
||||||
|
Argument('ldap_password', help='LDAP密码不能为空'),
|
||||||
|
).parse(request.body)
|
||||||
|
if error is None:
|
||||||
|
ldap = LDAP(form.server, form.admin_dn, form.admin_password, form.user_ou, form.user_filter, form.map_username, form.map_nickname)
|
||||||
|
status, msg = ldap.verify_user(form.ldap_user, form.ldap_password)
|
||||||
|
if status:
|
||||||
|
return json_response()
|
||||||
|
return json_response(error=msg)
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,26 +5,68 @@ import ldap
|
||||||
|
|
||||||
|
|
||||||
class LDAP:
|
class LDAP:
|
||||||
def __init__(self, server, port, rules, admin_dn, password, base_dn):
|
def __init__(self, server, admin_dn, admin_password, user_ou, user_filter, map_username, map_nickname):
|
||||||
self.server = server
|
self.server = server
|
||||||
self.port = port
|
|
||||||
self.rules = rules
|
|
||||||
self.admin_dn = admin_dn
|
self.admin_dn = admin_dn
|
||||||
self.password = password
|
self.admin_dn = admin_dn
|
||||||
self.base_dn = base_dn
|
self.admin_password = admin_password
|
||||||
|
self.user_ou = user_ou
|
||||||
|
self.user_filter = user_filter
|
||||||
|
self.map_username = map_username
|
||||||
|
self.map_nickname = map_nickname
|
||||||
|
|
||||||
def valid_user(self, username, password):
|
|
||||||
|
def connect(self):
|
||||||
try:
|
try:
|
||||||
conn = ldap.initialize("ldap://{0}:{1}".format(self.server, self.port), bytes_mode=False)
|
conn = ldap.initialize(f'{self.server}', bytes_mode=False)
|
||||||
conn.simple_bind_s(self.admin_dn, self.password)
|
conn.set_option(ldap.OPT_TIMEOUT, 3)
|
||||||
search_filter = f'({self.rules}={username})'
|
conn.set_option(ldap.OPT_NETWORK_TIMEOUT, 3)
|
||||||
ldap_result_id = conn.search(self.base_dn, ldap.SCOPE_SUBTREE, search_filter, None)
|
conn.simple_bind_s(self.admin_dn, self.admin_password)
|
||||||
result_type, result_data = conn.result(ldap_result_id, 0)
|
return True, conn
|
||||||
if result_type == ldap.RES_SEARCH_ENTRY:
|
|
||||||
conn.simple_bind_s(result_data[0][0], password)
|
|
||||||
return True, None
|
|
||||||
else:
|
|
||||||
return False, None
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
args = error.args
|
return False, error.args[0].get('desc')
|
||||||
return False, args[0].get('desc', '未知错误') if args else '%s' % error
|
|
||||||
|
|
||||||
|
def all_user(self):
|
||||||
|
status, conn = self.connect()
|
||||||
|
if status:
|
||||||
|
try:
|
||||||
|
# user_filter = '(cn=*)'
|
||||||
|
# map = ['cn', 'sn']
|
||||||
|
# user_map = list(self.user_map.values())
|
||||||
|
user_filter = "({}=*)".format(self.user_filter.split('=')[0][1:])
|
||||||
|
user_map = [self.map_username, self.map_nickname]
|
||||||
|
ldap_result = conn.search_s(self.user_ou, ldap.SCOPE_SUBTREE, user_filter, user_map)
|
||||||
|
ldap_users = []
|
||||||
|
for dn,entry in ldap_result:
|
||||||
|
if dn == self.user_ou:
|
||||||
|
continue
|
||||||
|
tmp_user = {}
|
||||||
|
for k,v in entry.items():
|
||||||
|
tmp_user.update({k: v[0].decode()})
|
||||||
|
|
||||||
|
ldap_users.append(tmp_user)
|
||||||
|
return True, ldap_users
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
return False, error.args[0].get('desc')
|
||||||
|
else:
|
||||||
|
return False, conn
|
||||||
|
|
||||||
|
def verify_user(self, username, password):
|
||||||
|
status, conn = self.connect()
|
||||||
|
if status:
|
||||||
|
try:
|
||||||
|
user_filter = f'({self.map_username}={username})'
|
||||||
|
ldap_result_id = conn.search(self.user_ou, ldap.SCOPE_SUBTREE, user_filter, [self.map_username])
|
||||||
|
_, result_data = conn.result(ldap_result_id, 0)
|
||||||
|
if result_data:
|
||||||
|
conn.simple_bind_s(result_data[0][0], password)
|
||||||
|
return True, True
|
||||||
|
else:
|
||||||
|
return False, '账户未找到'
|
||||||
|
except Exception as error:
|
||||||
|
return False, error.args[0].get('desc')
|
||||||
|
else:
|
||||||
|
return False, conn
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
*/
|
*/
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
import { Form, Button, Input, Space, message } from 'antd';
|
import { Form, Button, Input, Space, message, Modal } from 'antd';
|
||||||
import { http } from 'libs';
|
import { http } from 'libs';
|
||||||
|
import LdapImport from './LdapImport';
|
||||||
import { observer } from 'mobx-react'
|
import { observer } from 'mobx-react'
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ export default observer(function () {
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
store.loading = true;
|
store.loading = true;
|
||||||
const formData = form.getFieldsValue();
|
const formData = form.getFieldsValue();
|
||||||
http.post('/api/setting/', {data: [{key: 'ldap_service', value: formData}]})
|
http.post('/api/setting/', { data: [{ key: 'ldap_service', value: formData }] })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
message.success('保存成功');
|
message.success('保存成功');
|
||||||
store.fetchSettings()
|
store.fetchSettings()
|
||||||
|
@ -28,39 +29,78 @@ export default observer(function () {
|
||||||
function ldapTest() {
|
function ldapTest() {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const formData = form.getFieldsValue();
|
const formData = form.getFieldsValue();
|
||||||
http.post('/api/setting/ldap_test/', formData).then(() => {
|
http.post('/api/setting/ldap_test/', formData).then((res) => {
|
||||||
message.success('LDAP服务连接成功')
|
message.success("成功匹配" + res.length + "个用户")
|
||||||
}).finally(() => setLoading(false))
|
}).finally(() => setLoading(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ldapLogin(info) {
|
||||||
|
let ldadUser;
|
||||||
|
let ldadPwd;
|
||||||
|
Modal.confirm({
|
||||||
|
title: 'LDAP用户测试登录',
|
||||||
|
content: <Form layout="vertical" style={{marginTop: 24}}>
|
||||||
|
<Form.Item required label="LDAP用户名">
|
||||||
|
<Input onChange={val => ldadUser = val.target.value }/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item required label="LDAP用户密码" >
|
||||||
|
<Input.Password onChange={val => ldadPwd = val.target.value}/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>,
|
||||||
|
onOk: () => {
|
||||||
|
setLoading(true);
|
||||||
|
const formData = form.getFieldsValue();
|
||||||
|
formData.ldap_user = ldadUser;
|
||||||
|
formData.ldap_password = ldadPwd;
|
||||||
|
return http.post('/api/setting/ldap/', formData)
|
||||||
|
.then(() => message.success('登录成功', 1)).finally(() => setLoading(false))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className={styles.title}>LDAP设置</div>
|
<div className={styles.title}>LDAP设置</div>
|
||||||
<Form form={form} initialValues={store.settings.ldap_service} style={{maxWidth: 400}} labelCol={{span: 8}}
|
<Form form={form} initialValues={store.settings.ldap_service} style={{ maxWidth: 400 }} labelCol={{ span: 8 }}
|
||||||
wrapperCol={{span: 16}}>
|
wrapperCol={{ span: 16 }}>
|
||||||
<Form.Item required name="server" label="LDAP服务地址">
|
<Form.Item required name="server" label="LDAP服务地址" >
|
||||||
<Input placeholder="例如:ldap.spug.cc"/>
|
<Input placeholder="例如:ldap://127.0.0.1:389" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required name="port" label="LDAP服务端口">
|
|
||||||
<Input placeholder="例如:389"/>
|
<Form.Item required name="admin_dn" label="绑定DN" >
|
||||||
|
<Input placeholder="例如:cn=admin,dc=spug,dc=cc" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required name="admin_dn" label="管理员DN">
|
<Form.Item required name="admin_password" label="密码">
|
||||||
<Input placeholder="例如:cn=admin,dc=spug,dc=dev"/>
|
<Input.Password placeholder="LDAP管理密码" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required name="password" label="管理员密码">
|
|
||||||
<Input.Password placeholder="请输入LDAP管理员密码"/>
|
<Form.Item required name="user_ou" label="用户OU">
|
||||||
|
<Input placeholder="例如:ou=users,dc=spug,dc=cc" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required name="rules" label="LDAP搜索规则">
|
|
||||||
<Input placeholder="例如:cn"/>
|
<Form.Item required name="user_filter" label="用户过滤器">
|
||||||
|
<Input placeholder="例如:(cn或uid或sAMAccountName=%(user)s)" value="(cn=%(user)s)" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required name="base_dn" label="基本DN">
|
{/* <Form.Item required name="user_map" label="用户属性映射" extra="用户属性映射代表怎样将LDAP中用户属性映射到Spug用户上,username, nickname 是Spug的用户需要属性">
|
||||||
<Input placeholder="例如:dc=spug,dc=dev"/>
|
<Input.TextArea row={4} placeholder="例如:" />
|
||||||
|
</Form.Item> */}
|
||||||
|
|
||||||
|
<Form.Item required name="map_username" label="登录名映射" extra="登录名映射代表将LDAP用户的某个属性映射到Spug的登录名中,例如cn对应登录名">
|
||||||
|
<Input placeholder="例如:cn" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item required name="map_nickname" label="姓名映射" extra="姓名映射代表将LDAP用户的某个属性映射到Spug的姓名中,例如sn对应姓名">
|
||||||
|
<Input placeholder="例如:sn" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Space>
|
<Space>
|
||||||
<Button type="danger" loading={loading} onClick={ldapTest}>测试LDAP</Button>
|
<Button loading={loading} onClick={ldapTest}>测试连接</Button>
|
||||||
|
<Button loading={loading} onClick={ldapLogin}>测试登录</Button>
|
||||||
|
<Button loading={loading} onClick={store.handleLdapImport}>用户导入</Button>
|
||||||
<Button type="primary" loading={store.loading} onClick={handleSubmit}>保存设置</Button>
|
<Button type="primary" loading={store.loading} onClick={handleSubmit}>保存设置</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</Form>
|
</Form>
|
||||||
|
{store.importVisible && <LdapImport />}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
})
|
})
|
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
|
* Released under the AGPL-3.0 License.
|
||||||
|
*/
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Modal, Input, message, Badge, Button } from 'antd';
|
||||||
|
import http from 'libs/http';
|
||||||
|
import { TableCard } from 'components';
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
|
|
||||||
|
export default observer(function () {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||||
|
|
||||||
|
function handleImportSelect() {
|
||||||
|
setLoading(true);
|
||||||
|
let ldap_data = [];
|
||||||
|
for (let item of store.dataSource) {
|
||||||
|
if (selectedRowKeys.includes(item.id)) {
|
||||||
|
ldap_data.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleSubmit(ldap_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleImportAll() {
|
||||||
|
setLoading(true);
|
||||||
|
handleSubmit(store.dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(data) {
|
||||||
|
if (data) {
|
||||||
|
http.post('/api/setting/ldap_import/',
|
||||||
|
{'ldap_data': data, 'username': store.username, 'nickname': store.nickname})
|
||||||
|
.then(() => {
|
||||||
|
message.success('操作成功');
|
||||||
|
store.importVisible = false;
|
||||||
|
}, () => setLoading(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClickRow(record) {
|
||||||
|
let tmp = new Set(selectedRowKeys)
|
||||||
|
if (!tmp.delete(record.id)) {
|
||||||
|
tmp.add(record.id)
|
||||||
|
}
|
||||||
|
setSelectedRowKeys([...tmp])
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelectAll(selected) {
|
||||||
|
let tmp = new Set(selectedRowKeys)
|
||||||
|
for (let item of store.dataSource) {
|
||||||
|
if (selected) {
|
||||||
|
tmp.add(item.id)
|
||||||
|
} else {
|
||||||
|
tmp.delete(item.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setSelectedRowKeys([...tmp])
|
||||||
|
}
|
||||||
|
|
||||||
|
let columns = [{
|
||||||
|
title: '登录名',
|
||||||
|
dataIndex: "cn",
|
||||||
|
}, {
|
||||||
|
title: '姓名',
|
||||||
|
dataIndex: "sn",
|
||||||
|
}, {
|
||||||
|
title: '是否存在',
|
||||||
|
render: text => text.is_exist ? <Badge status="success" text='是' /> : <Badge status="error" text='否' />,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
visible
|
||||||
|
width={700}
|
||||||
|
maskClosable={false}
|
||||||
|
title={'Ldap用户导入'}
|
||||||
|
onCancel={() => store.importVisible = false}
|
||||||
|
confirmLoading={loading}
|
||||||
|
onOk={handleImportAll}
|
||||||
|
footer={[
|
||||||
|
<Button key="back" onClick={() => store.importVisible = false}>取消</Button>,
|
||||||
|
<Button key="select" type="primary" loading={loading} onClick={handleImportSelect}>导入选中</Button>,
|
||||||
|
<Button key="import" type="primary" loading={loading} onClick={handleImportAll}>导入全部</Button>,
|
||||||
|
]}>
|
||||||
|
|
||||||
|
<TableCard
|
||||||
|
tKey="sa"
|
||||||
|
rowKey="id"
|
||||||
|
title="LDAP用户列表"
|
||||||
|
loading={store.isFetching}
|
||||||
|
dataSource={store.dataSource}
|
||||||
|
onReload={store.fetchLdapRecords}
|
||||||
|
onRow={record => {
|
||||||
|
return {
|
||||||
|
onClick: () => handleClickRow(record)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
actions={[
|
||||||
|
<Input value={store.f_name} onChange={e => store.f_name = e.target.value } placeholder="搜索LDAP用户" />,
|
||||||
|
]}
|
||||||
|
pagination={{
|
||||||
|
showSizeChanger: true,
|
||||||
|
showLessItems: true,
|
||||||
|
showTotal: total => `共 ${total} 条`,
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100']
|
||||||
|
}}
|
||||||
|
rowSelection={{
|
||||||
|
selectedRowKeys,
|
||||||
|
onSelect: handleClickRow,
|
||||||
|
onSelectAll: handleSelectAll
|
||||||
|
}}
|
||||||
|
columns={columns} />
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
})
|
|
@ -3,13 +3,23 @@
|
||||||
* Copyright (c) <spug.dev@gmail.com>
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import { observable } from "mobx";
|
import { observable, computed } from "mobx";
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
|
|
||||||
class Store {
|
class Store {
|
||||||
@observable settings = {};
|
@observable settings = {};
|
||||||
@observable isFetching = false;
|
@observable isFetching = false;
|
||||||
@observable loading = false;
|
@observable loading = false;
|
||||||
|
@observable importVisible = false;
|
||||||
|
@observable records = [];
|
||||||
|
@observable f_name;
|
||||||
|
|
||||||
|
@computed get dataSource() {
|
||||||
|
let records = this.records;
|
||||||
|
if (this.f_name) records = records.filter(x => x.cn.toLowerCase().includes(this.f_name.toLowerCase()));
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fetchSettings = () => {
|
fetchSettings = () => {
|
||||||
this.isFetching = true;
|
this.isFetching = true;
|
||||||
|
@ -21,6 +31,22 @@ class Store {
|
||||||
update = (key, value) => {
|
update = (key, value) => {
|
||||||
this.settings[key] = value
|
this.settings[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fetchLdapRecords = () => {
|
||||||
|
this.isFetching = true;
|
||||||
|
http.get('/api/setting/ldap/')
|
||||||
|
.then((res) => {
|
||||||
|
this.records = res;
|
||||||
|
})
|
||||||
|
.finally(() => this.isFetching = false)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
handleLdapImport = () => {
|
||||||
|
this.importVisible = true;
|
||||||
|
this.fetchLdapRecords();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Store()
|
export default new Store()
|
||||||
|
|
Loading…
Reference in New Issue