1. 导入LDAP用户时仅列出尚未导入的用户; 2. 导入LDAP用户时根据情况会发送通知邮件; 3. 涉及到发送邮件的操作,页面超时加长了,减少出现“网络故障”的错误提示。

pull/236/head
Apex Liu 2019-01-08 06:26:54 +08:00
parent c16d32e6d5
commit 051c79a053
6 changed files with 80 additions and 103 deletions

View File

@ -17,7 +17,6 @@ $app.on_init = function (cb_stack) {
btn_ldap_import: $('a[data-action="ldap-import"]'),
btn_ldap_config: $('a[data-action="ldap-config"]'),
btn_ldap_sync: $('a[data-action="ldap-sync"]'),
dlg_import_user: $('#dlg-import-user'),
btn_import_user: $('#btn-import-user'),
@ -28,18 +27,12 @@ $app.on_init = function (cb_stack) {
};
cb_stack
// .add($app.test)
.add($app.create_controls)
.add($app.load_role_list);
cb_stack.exec();
};
$app.test = function (cb) {
cb.add($app.dlg_ldap_config.show);
cb.exec();
};
//===================================
// 创建页面控件对象
//===================================
@ -996,7 +989,7 @@ $app.create_dlg_edit_user = function () {
return;
var action = (dlg.field_id === -1) ? '创建' : '更新';
var timeout = (dlg.field_id === -1) ? 60000 : 3000;
var timeout = (dlg.field_id === -1) ? 60000 : 30000;
// 如果id为-1表示创建否则表示更新
$tp.ajax_post_json('/user/update-user', {
@ -1208,7 +1201,8 @@ $app.create_dlg_reset_password = function () {
function () {
dlg.dom.btn_send_reset_email.removeAttr('disabled');
$tp.notify_error('网络故障,用户密码重置失败!');
}
},
60000
);
};
@ -1619,16 +1613,17 @@ $app.create_dlg_ldap_import = function () {
key: "email",
// width: 120,
sort: false
},
{
title: "状态",
key: "bind",
sort: false,
width: 80,
align: 'center',
render: 'ldap_user_state',
fields: {bind: 'bind'}
}
// ,
// {
// title: "状态",
// key: "bound",
// sort: false,
// width: 80,
// align: 'center',
// render: 'ldap_user_state',
// fields: {bound: 'bound'}
// }
],
// 重载回调函数
@ -1688,11 +1683,11 @@ $app.create_dlg_ldap_import = function () {
return '<span><input type="checkbox" data-check-box="' + fields.id + '" data-row-id="' + row_id + '"></span>';
};
render.user_state = function (row_id, fields) {
if (fields.bind) {
return '已导入';
}
};
// render.ldap_user_state = function (row_id, fields) {
// if (fields.bound) {
// return '已导入';
// }
// };
};
dlg.check_user_list_all_selected = function (cb_stack) {
@ -1782,7 +1777,7 @@ $app.create_dlg_ldap_import = function () {
dlg.dom.btn_import.removeAttr('disabled');
$tp.notify_error('网络故障导入LDAP用户失败');
},
15000
60000
);
};

View File

@ -53,22 +53,12 @@
<button id="btn-import-user" class="btn btn-sm btn-default"><i class="fa fa-plus-square fa-fw"></i> 导入用户
</button>
<div class="btn-group btn-group-sm dropdown" id="filter-host-group">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"><i
class="fas fa-address-book fa-fw"></i> LDAP管理(试验) <i class="fa fa-caret-right"></i></button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"><i class="fas fa-address-book fa-fw"></i> LDAP管理 <i class="fa fa-caret-right"></i></button>
<ul class="dropdown-menu dropdown-menu-right dropdown-menu-sm">
<li>
<li><a href="javascript:;" data-action="ldap-import"><i
class="fas fa-arrow-alt-circle-left fa-fw"></i> 导入LDAP用户</a></li>
</li>
<li><a href="javascript:;" data-action="ldap-import"><i class="fas fa-arrow-alt-circle-left fa-fw"></i> 导入LDAP用户</a></li>
<li role="separator" class="divider"></li>
<li>
<li><a href="javascript:;" data-action="ldap-config"><i class="fas fa-cog fa-fw"></i> 设置LDAP</a>
</li>
</li>
<li>
<li><a href="javascript:;" data-action="ldap-sync"><i class="fas fa-link fa-fw"></i> 同步LDAP</a>
</li>
</li>
<li><a href="javascript:;" data-action="ldap-config"><i class="fas fa-cog fa-fw"></i> 设置LDAP</a></li>
## <li><a href="javascript:;" data-action="ldap-sync"><i class="fas fa-link fa-fw"></i> 同步LDAP</a></li>
</ul>
</div>
</div>
@ -436,7 +426,7 @@
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
class="fa fa-times-circle fa-fw"></i></button>
<h3 class="modal-title">LDAP设置 (实验性)</h3>
<h3 class="modal-title">LDAP设置</h3>
</div>
<div class="modal-body">
@ -558,15 +548,6 @@
</div>
</div>
## <div class="form-group form-group-sm">
## <label for="edit-ldap-attr-map" class="col-sm-2 control-label require">属性映射:</label>
## <div class="col-sm-9">
## <textarea id="edit-ldap-attr-map" class="form-control" style="resize:vertical;height:8em;" placeholder=""></textarea>
## <div class="control-desc-sm">将LDAP的属性映射到 teleport 的用户属性,例如 <span class="important">LDAP中的用户属性 sAMAccountName 映射为teleport的登录账号</span>。如果不清楚此LDAP服务的用户属性可使用下方的“列举属性”按钮进行查询。</div>
## </div>
## </div>
</div>
</div>
@ -684,7 +665,7 @@
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
class="fa fa-times-circle fa-fw"></i></button>
<h3 class="modal-title">导入LDAP用户(试验)</h3>
<h3 class="modal-title">导入LDAP用户</h3>
</div>
<div class="modal-body">

View File

@ -8,8 +8,6 @@ import hashlib
import threading
import random
__all__ = ['AttrDict', 'tp_make_dir', 'tp_timestamp_utc_now', 'tp_generate_random']
class AttrDict(dict):
"""

View File

@ -552,20 +552,28 @@ class DoLdapGetUsersHandler(TPBaseJsonHandler):
try:
ldap = Ldap(_server, _port, _base_dn)
ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_username, _attr_surname, _attr_email)
if ret != TPE_OK:
return self.write_json(ret, message=err_msg)
else:
# TODO: search all user in database to check if the LDAP user have already bind.
ret_data = []
for u in data:
h = hashlib.sha1()
h.update(u.encode())
user = data[u]
user['bind'] = False
user['id'] = h.hexdigest()
ret_data.append(user)
return self.write_json(ret, data=ret_data)
exits_users = user.get_users_by_type(TP_USER_TYPE_LDAP)
bound_users = []
for u in exits_users:
h = hashlib.sha1()
h.update(u['ldap_dn'].encode())
bound_users.append(h.hexdigest())
ret_data = []
for u in data:
h = hashlib.sha1()
h.update(u.encode())
_id = h.hexdigest()
if _id in bound_users:
continue
_user = data[u]
_user['id'] = h.hexdigest()
ret_data.append(_user)
return self.write_json(ret, data=ret_data)
except:
log.e('')
return self.write_json(TPE_PARAM)
@ -610,25 +618,24 @@ class DoLdapImportHandler(TPBaseJsonHandler):
if ret != TPE_OK:
return self.write_json(ret, message=err_msg)
else:
# TODO: search all user in database to check if the LDAP user have already bind.
need_import = []
for u in data:
h = hashlib.sha1()
h.update(u.encode())
dn_hash = h.hexdigest()
for x in dn_hash_list:
if x == dn_hash:
_user = data[u]
_user['dn'] = u
need_import.append(_user)
break
need_import = []
for u in data:
h = hashlib.sha1()
h.update(u.encode())
if len(need_import) == 0:
return self.write_json(ret, message='没有可以导入的LDAP用户')
dn_hash = h.hexdigest()
for x in dn_hash_list:
if x == dn_hash:
_user = data[u]
_user['dn'] = u
need_import.append(_user)
break
return self._do_import(need_import)
if len(need_import) == 0:
return self.write_json(ret, message='没有可以导入的LDAP用户')
return self._do_import(need_import)
except:
log.e('')
return self.write_json(TPE_PARAM)
@ -665,6 +672,7 @@ class DoLdapImportHandler(TPBaseJsonHandler):
user_list.append(u)
print(user_list)
user.create_users(self, user_list, success, failed)
# 对于创建成功的用户,发送密码邮件函
@ -674,29 +682,17 @@ class DoLdapImportHandler(TPBaseJsonHandler):
for u in user_list:
if u['_id'] == 0 or len(u['email']) == 0:
continue
u['email'] = 'apex.liu@qq.com'
mmm = '{surname} 您好!\n\n已为您创建teleport系统用户账号现在可以使用以下信息登录teleport系统\n\n'
'登录用户名:{username}\n'
'密码:您正在使用的密码\n'
'地址:{web_url}\n\n\n\n'
'[本邮件由teleport系统自动发出请勿回复]'
'\n\n'
''.format(surname=u['surname'], username=u['username'], web_url=web_url)
print(mmm)
mail_body = '{surname} 您好!\n\n已为您创建teleport系统用户账号现在可以使用以下信息登录teleport系统\n\n' \
'登录用户名:{username}\n' \
'密码:您正在使用的域登录密码\n' \
'地址:{web_url}\n\n\n\n' \
'[本邮件由teleport系统自动发出请勿回复]' \
'\n\n' \
''.format(surname=u['surname'], username=u['username'], web_url=web_url)
err = TPE_FAILED
msg = 'test bad.'
# err, msg = yield mail.tp_send_mail(
# u['email'],
# '{surname} 您好!\n\n已为您创建teleport系统用户账号现在可以使用以下信息登录teleport系统\n\n'
# '登录用户名:{username}\n'
# '密码:您正在使用的密码\n'
# '地址:{web_url}\n\n\n\n'
# '[本邮件由teleport系统自动发出请勿回复]'
# '\n\n'
# ''.format(surname=u['surname'], username=u['username'], web_url=web_url),
# subject='用户密码函'
# )
err, msg = yield mail.tp_send_mail(u['email'], mail_body, subject='用户密码函')
if err != TPE_OK:
failed.append({'line': u['_line'], 'error': '无法发送密码函到邮箱 {},错误:{}'.format(u['email'], msg)})

View File

@ -12,14 +12,11 @@ from app.base.controller import TPBaseHandler, TPBaseJsonHandler
from app.base.logger import *
from app.base.session import tp_session
from app.base.utils import tp_check_strong_password, tp_gen_password
# from app.base.utils import tp_timestamp_utc_now
from app.logic.auth.oath import tp_oath_verify_code
from app.const import *
from app.logic.auth.oath import tp_oath_generate_secret, tp_oath_generate_qrcode
from app.logic.auth.password import tp_password_generate_secret, tp_password_verify
from app.logic.auth.ldap import Ldap
from app.model import group
# from app.model import syslog
from app.model import user

View File

@ -246,6 +246,16 @@ def get_users(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
return err, s.total_count, s.page_index, s.recorder
def get_users_by_type(_type):
s = SQL(get_db())
err = s.select_from('user', ['id', 'type', 'ldap_dn'], alt_name='u').where('u.type={}'.format(_type)).query()
if err != TPE_OK:
return None
if len(s.recorder) == 0:
return None
return s.recorder
def create_users(handler, user_list, success, failed):
"""
批量创建用户