mirror of https://github.com/tp4a/teleport
..LDAP用户导入功能完成,准备实现导入用户的登录功能。
parent
4c14a58877
commit
493e991787
|
@ -28,7 +28,7 @@ $app.on_init = function (cb_stack) {
|
|||
};
|
||||
|
||||
cb_stack
|
||||
.add($app.test)
|
||||
// .add($app.test)
|
||||
.add($app.create_controls)
|
||||
.add($app.load_role_list);
|
||||
|
||||
|
@ -109,7 +109,7 @@ $app.create_controls = function (cb_stack) {
|
|||
align: 'center',
|
||||
width: 70,
|
||||
render: 'make_action_btn',
|
||||
fields: {id: 'id', state: 'state'}
|
||||
fields: {id: 'id', state: 'state', user_type: 'type'}
|
||||
}
|
||||
],
|
||||
|
||||
|
@ -144,6 +144,7 @@ $app.create_controls = function (cb_stack) {
|
|||
});
|
||||
$tp.create_table_pagination($app.table_users, 'table-user-list-pagination');
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// 对话框
|
||||
//-------------------------------
|
||||
|
@ -190,7 +191,7 @@ $app.create_controls = function (cb_stack) {
|
|||
$app.dlg_ldap_import = $app.create_dlg_ldap_import();
|
||||
cb_stack.add($app.dlg_ldap_import.init);
|
||||
$app.dom.btn_ldap_import.click(function () {
|
||||
if(0 === $app.options.sys_cfg.ldap.server.length) {
|
||||
if (0 === $app.options.sys_cfg.ldap.server.length) {
|
||||
$tp.notify_error('LDAP服务尚未设置,请先设置!');
|
||||
return;
|
||||
}
|
||||
|
@ -239,12 +240,19 @@ $app.on_table_users_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
|||
if (action === 'edit') {
|
||||
$app.dlg_edit_user.show_edit(row_id);
|
||||
} else if (action === 'reset-password') {
|
||||
console.log(user);
|
||||
if(user.type === TP_USER_TYPE_LDAP)
|
||||
return;
|
||||
$app.dlg_reset_password.show_edit(row_id);
|
||||
} else if (action === 'reset-oath-bind') {
|
||||
$app._reset_oath_bind(user.id);
|
||||
} else if (action === 'lock') {
|
||||
if (user.state !== TP_STATE_NORMAL)
|
||||
return;
|
||||
$app._lock_users([user.id]);
|
||||
} else if (action === 'unlock') {
|
||||
if (user.state === TP_STATE_NORMAL)
|
||||
return;
|
||||
$app._unlock_users([user.id]);
|
||||
} else if (action === 'remove') {
|
||||
$app._remove_users([user.id]);
|
||||
|
@ -411,7 +419,15 @@ $app.on_table_users_render_created = function (render) {
|
|||
h.push('<li' + class_unlock + '><a href="javascript:;" data-action="unlock"><i class="fa fa-unlock fa-fw"></i> 解禁</a></li>');
|
||||
|
||||
h.push('<li role="separator" class="divider"></li>');
|
||||
h.push('<li><a href="javascript:;" data-action="reset-password"><i class="fa fa-street-view fa-fw"></i> 重置密码</a></li>');
|
||||
|
||||
var class_user_type = '';
|
||||
if (fields.user_type === TP_USER_TYPE_LDAP) {
|
||||
class_user_type = ' class="disabled"';
|
||||
} else {
|
||||
class_user_type = '';
|
||||
}
|
||||
h.push('<li' + class_user_type +'><a href="javascript:;" data-action="reset-password"><i class="fa fa-street-view fa-fw"></i> 重置密码</a></li>');
|
||||
|
||||
h.push('<li><a href="javascript:;" data-action="reset-oath-bind"><i class="fa fa-street-view fa-fw"></i> 重置身份验证器</a></li>');
|
||||
h.push('<li role="separator" class="divider"></li>');
|
||||
h.push('<li><a href="javascript:;" data-action="remove"><i class="fa fa-times-circle fa-fw"></i> 删除</a></li>');
|
||||
|
@ -1288,7 +1304,7 @@ $app.create_dlg_ldap_config = function () {
|
|||
};
|
||||
|
||||
dlg.init_fields = function () {
|
||||
if(0 === $app.options.sys_cfg.ldap.server.length) {
|
||||
if (0 === $app.options.sys_cfg.ldap.server.length) {
|
||||
dlg.mode = 'set';
|
||||
} else {
|
||||
dlg.ldap_config = $app.options.sys_cfg.ldap;
|
||||
|
@ -1348,7 +1364,7 @@ $app.create_dlg_ldap_config = function () {
|
|||
return false;
|
||||
}
|
||||
|
||||
if(dlg.mode === 'set') {
|
||||
if (dlg.mode === 'set') {
|
||||
if (tp_is_empty_str(dlg.ldap_config.password)) {
|
||||
dlg.dom.password.focus();
|
||||
$tp.notify_error('请填写LDAP的管理员密码!');
|
||||
|
@ -1436,6 +1452,7 @@ $app.create_dlg_ldap_config = function () {
|
|||
dlg.dom.btn_save.removeAttr('disabled');
|
||||
if (ret.code === TPE_OK) {
|
||||
$app.options.sys_cfg.ldap = dlg.ldap_config;
|
||||
dlg.dom.dialog.modal('hide');
|
||||
$tp.notify_success('保存LDAP设置成功!');
|
||||
} else {
|
||||
$tp.notify_error('保存LDAP设置失败:' + tp_error_msg(ret.code, ret.message));
|
||||
|
@ -1546,32 +1563,172 @@ $app.create_dlg_ldap_import = function () {
|
|||
dialog: $('#' + dlg.dom_id),
|
||||
table: $('#table-ldap-import'),
|
||||
|
||||
chkbox_user_list_select_all: $('#table-ldap-user-select-all'),
|
||||
|
||||
btn_refresh: $('#btn-ldap-import-refresh'),
|
||||
btn_import: $('#btn-ldap-import-import')
|
||||
};
|
||||
|
||||
dlg.init = function (cb_stack) {
|
||||
dlg.dom.btn_refresh.click(dlg.do_refresh);
|
||||
|
||||
//-------------------------------
|
||||
// LDAP用户列表表格
|
||||
//-------------------------------
|
||||
var table_ldap_users_options = {
|
||||
dom_id: 'table-ldap-user-list',
|
||||
data_source: {
|
||||
type: 'none'
|
||||
},
|
||||
column_default: {sort: false, align: 'left'},
|
||||
columns: [
|
||||
{
|
||||
// title: '<input type="checkbox" id="user-list-select-all" value="">',
|
||||
title: '',
|
||||
key: 'chkbox',
|
||||
sort: false,
|
||||
width: 36,
|
||||
align: 'center',
|
||||
render: 'make_check_box',
|
||||
fields: {id: 'id'}
|
||||
},
|
||||
{
|
||||
title: "用户名",
|
||||
key: "username",
|
||||
sort: false
|
||||
},
|
||||
{
|
||||
title: "姓名",
|
||||
key: "surname",
|
||||
// width: 120,
|
||||
sort: false
|
||||
},
|
||||
{
|
||||
title: "邮箱",
|
||||
key: "email",
|
||||
// width: 120,
|
||||
sort: false
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "bind",
|
||||
sort: false,
|
||||
width: 80,
|
||||
align: 'center',
|
||||
render: 'ldap_user_state',
|
||||
fields: {bind: 'bind'}
|
||||
}
|
||||
],
|
||||
|
||||
// 重载回调函数
|
||||
on_render_created: dlg.on_table_users_render_created,
|
||||
on_cell_created: dlg.on_table_users_cell_created
|
||||
};
|
||||
|
||||
$app.table_ldap_users = $tp.create_table(table_ldap_users_options);
|
||||
cb_stack
|
||||
.add($app.table_ldap_users.init);
|
||||
|
||||
dlg.dom.btn_refresh.click(function () {
|
||||
dlg.load_users();
|
||||
});
|
||||
|
||||
dlg.dom.chkbox_user_list_select_all.click(function () {
|
||||
var _objects = $('#' + $app.table_ldap_users.dom_id + ' tbody').find('[data-check-box]');
|
||||
if ($(this).is(':checked')) {
|
||||
$.each(_objects, function (i, _obj) {
|
||||
$(_obj).prop('checked', true);
|
||||
});
|
||||
} else {
|
||||
$.each(_objects, function (i, _obj) {
|
||||
$(_obj).prop('checked', false);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// dlg.dom.btn_refresh.click(dlg.load_users);
|
||||
dlg.dom.btn_import.click(dlg.do_import);
|
||||
cb_stack.exec();
|
||||
};
|
||||
|
||||
dlg.show = function () {
|
||||
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||
dlg.do_refresh();
|
||||
dlg.get_selected_user = function (tbl) {
|
||||
var items = [];
|
||||
var _objs = $('#' + tbl.dom_id + ' tbody tr td input[data-check-box]');
|
||||
$.each(_objs, function (i, _obj) {
|
||||
if ($(_obj).is(':checked')) {
|
||||
var _row_data = tbl.get_row(_obj);
|
||||
items.push(_row_data.id);
|
||||
}
|
||||
});
|
||||
return items;
|
||||
};
|
||||
|
||||
dlg.do_refresh = function () {
|
||||
dlg.on_table_users_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
||||
if (col_key === 'chkbox') {
|
||||
cell_obj.find('[data-check-box]').click(function () {
|
||||
dlg.check_user_list_all_selected();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
dlg.on_table_users_render_created = function (render) {
|
||||
|
||||
render.make_check_box = function (row_id, fields) {
|
||||
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 '已导入';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
dlg.check_user_list_all_selected = function (cb_stack) {
|
||||
var _all_checked = true;
|
||||
var _objs = $('#' + $app.table_ldap_users.dom_id + ' tbody').find('[data-check-box]');
|
||||
if (_objs.length === 0) {
|
||||
_all_checked = false;
|
||||
} else {
|
||||
$.each(_objs, function (i, _obj) {
|
||||
if (!$(_obj).is(':checked')) {
|
||||
_all_checked = false;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (_all_checked) {
|
||||
dlg.dom.chkbox_user_list_select_all.prop('checked', true);
|
||||
} else {
|
||||
dlg.dom.chkbox_user_list_select_all.prop('checked', false);
|
||||
}
|
||||
|
||||
if (cb_stack)
|
||||
cb_stack.exec();
|
||||
};
|
||||
|
||||
dlg.show = function () {
|
||||
dlg.load_users();
|
||||
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||
};
|
||||
|
||||
dlg.load_users = function (cb_stack) {
|
||||
cb_stack = cb_stack || CALLBACK_STACK.create();
|
||||
|
||||
dlg.dom.btn_refresh.attr('disabled', 'disabled');
|
||||
$tp.ajax_post_json('/system/do-ldap-get-users', {
|
||||
},
|
||||
$tp.ajax_post_json('/system/do-ldap-get-users', {},
|
||||
function (ret) {
|
||||
dlg.dom.btn_refresh.removeAttr('disabled');
|
||||
if (ret.code === TPE_OK) {
|
||||
// $tp.notify_success('列举LDAP用户成功!');
|
||||
console.log(ret.data);
|
||||
//$app.dlg_ldap_test_result.show(ret.data);
|
||||
dlg._show_users(ret.data);
|
||||
|
||||
var _d = [];
|
||||
for (var i = 0; i < ret.data.length; ++i) {
|
||||
_d.push(ret.data[i]);
|
||||
}
|
||||
|
||||
cb_stack.add(dlg.check_user_list_all_selected);
|
||||
$app.table_ldap_users.set_data(cb_stack, {}, {total: ret.data.length, page_index: 1, data: _d});
|
||||
} else {
|
||||
$tp.notify_error('获取LDAP用户列表失败:' + tp_error_msg(ret.code, ret.message));
|
||||
}
|
||||
|
@ -1584,60 +1741,34 @@ $app.create_dlg_ldap_import = function () {
|
|||
);
|
||||
};
|
||||
|
||||
dlg._show_users = function(data) {
|
||||
dlg.dom.table.empty();
|
||||
|
||||
var attr_names = ['username', 'surname', 'email'];
|
||||
|
||||
var h = [];
|
||||
var dn, x;
|
||||
var th_created = false;
|
||||
for (dn in data) {
|
||||
if (!th_created) {
|
||||
h.push('<thead>');
|
||||
for (x in attr_names) {
|
||||
h.push('<th style="text-align:left;" class="mono">');
|
||||
h.push(attr_names[x]);
|
||||
h.push('</th>');
|
||||
}
|
||||
h.push('</thead>');
|
||||
th_created = true;
|
||||
}
|
||||
|
||||
h.push('<tr>');
|
||||
for (x in attr_names) {
|
||||
h.push('<td style="text-align:left;" class="mono">');
|
||||
if (!_.isEmpty(data[dn][attr_names[x]]))
|
||||
h.push(data[dn][attr_names[x]]);
|
||||
else
|
||||
h.push('');
|
||||
h.push('</td>');
|
||||
}
|
||||
h.push('</tr>');
|
||||
dlg.do_import = function () {
|
||||
var items = dlg.get_selected_user($app.table_ldap_users);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要导入的账号!');
|
||||
return;
|
||||
}
|
||||
|
||||
dlg.dom.table.append($(h.join('')));
|
||||
dlg.dom.dialog.modal();
|
||||
};
|
||||
console.log(items);
|
||||
|
||||
dlg.do_import = function () {
|
||||
if (!dlg.check_fields())
|
||||
return;
|
||||
dlg.dom.btn_save.attr('disabled', 'disabled');
|
||||
$tp.ajax_post_json('/system/do-ldap-import', {
|
||||
},
|
||||
dlg.dom.btn_import.attr('disabled', 'disabled');
|
||||
$tp.ajax_post_json('/system/do-ldap-import', {ldap_users: items},
|
||||
function (ret) {
|
||||
dlg.dom.btn_save.removeAttr('disabled');
|
||||
dlg.dom.btn_import.removeAttr('disabled');
|
||||
if (ret.code === TPE_OK) {
|
||||
$app.options.sys_cfg.ldap = dlg.ldap_config;
|
||||
$tp.notify_success('保存LDAP设置成功!');
|
||||
CALLBACK_STACK.create()
|
||||
.add($app.table_users.load_data)
|
||||
.add(dlg.check_user_list_all_selected)
|
||||
.add(dlg.load_users)
|
||||
.exec();
|
||||
|
||||
$tp.notify_success('导入LDAP用户成功!');
|
||||
} else {
|
||||
$tp.notify_error('保存LDAP设置失败:' + tp_error_msg(ret.code, ret.message));
|
||||
$tp.notify_error('导入LDAP用户失败:' + tp_error_msg(ret.code, ret.message));
|
||||
}
|
||||
},
|
||||
function () {
|
||||
dlg.dom.btn_save.removeAttr('disabled');
|
||||
$tp.notify_error('网络故障,保存LDAP设置失败!');
|
||||
dlg.dom.btn_import.removeAttr('disabled');
|
||||
$tp.notify_error('网络故障,导入LDAP用户失败!');
|
||||
},
|
||||
15000
|
||||
);
|
||||
|
|
|
@ -44,33 +44,42 @@
|
|||
<div class="table-prefix-area">
|
||||
<div class="table-extend-cell">
|
||||
<span class="table-name"><i class="fa fa-list fa-fw"></i> 用户列表</span>
|
||||
<button id="btn-refresh-user-list" class="btn btn-sm btn-default"><i class="fa fa-redo fa-fw"></i> 刷新列表</button>
|
||||
<button id="btn-refresh-user-list" class="btn btn-sm btn-default"><i class="fa fa-redo fa-fw"></i> 刷新列表
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-extend-cell table-extend-cell-right group-actions">
|
||||
<button id="btn-create-user" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 创建用户</button>
|
||||
<button id="btn-import-user" class="btn btn-sm btn-default"><i class="fa fa-plus-square fa-fw"></i> 导入用户</button>
|
||||
<button id="btn-create-user" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 创建用户
|
||||
</button>
|
||||
<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><a href="javascript:;" data-action="ldap-import"><i
|
||||
class="fas fa-arrow-alt-circle-left fa-fw"></i> 导入LDAP用户</a></li>
|
||||
</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><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><a href="javascript:;" data-action="ldap-sync"><i class="fas fa-link fa-fw"></i> 同步LDAP</a>
|
||||
</li>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="table-user-list" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
<table id="table-user-list"
|
||||
class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
|
||||
<div class="table-extend-area">
|
||||
<div class="table-extend-cell checkbox-select-all"><input id="table-user-list-select-all" type="checkbox"/></div>
|
||||
<div class="table-extend-cell checkbox-select-all"><input id="table-user-list-select-all" type="checkbox"/>
|
||||
</div>
|
||||
|
||||
## _ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select">');
|
||||
## _ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
||||
|
@ -88,14 +97,20 @@
|
|||
<div class="table-extend-cell group-actions">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group dropup" id="btn-set-role" role="group">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i class="fas fa-user fa-fw"></i> 设置角色 <i class="fa fa-caret-right"></i></button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i
|
||||
class="fas fa-user fa-fw"></i> 设置角色 <i class="fa fa-caret-right"></i></button>
|
||||
<ul class="dropdown-menu dropdown-menu-sm"></ul>
|
||||
</div>
|
||||
## <button id="btn-set-role" type="button" class="btn btn-default"><i class="fa fa-edit fa-fw"></i> 设置角色</button>
|
||||
|
||||
<button id="btn-lock-user" type="button" class="btn btn-default"><i class="fa fa-lock fa-fw"></i> 禁用</button>
|
||||
<button id="btn-unlock-user" type="button" class="btn btn-default"><i class="fa fa-unlock fa-fw"></i> 解禁</button>
|
||||
<button id="btn-remove-user" type="button" class="btn btn-default"><i class="fa fa-times-circle fa-fw"></i> 删除</button>
|
||||
<button id="btn-lock-user" type="button" class="btn btn-default"><i class="fa fa-lock fa-fw"></i> 禁用
|
||||
</button>
|
||||
<button id="btn-unlock-user" type="button" class="btn btn-default"><i
|
||||
class="fa fa-unlock fa-fw"></i> 解禁
|
||||
</button>
|
||||
<button id="btn-remove-user" type="button" class="btn btn-default"><i
|
||||
class="fa fa-times-circle fa-fw"></i> 删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-extend-cell table-item-counter">
|
||||
|
@ -119,7 +134,9 @@
|
|||
<p>说明:</p>
|
||||
<ul class="help-list">
|
||||
<li>可以通过表格标题栏进行搜索或过滤,以便快速定位你需要的信息。标题栏左侧的 <i class="fa fa-undo fa-fw"></i> 可以重置过滤器。</li>
|
||||
<li>批量导入用户需要上传.csv格式的文件,您可以 <a href="/static/download/teleport-example-user.csv"><i class="fa fa-download fa-fw"></i>下载用户信息文件模板</a> 进行编辑。</li>
|
||||
<li>批量导入用户需要上传.csv格式的文件,您可以 <a href="/static/download/teleport-example-user.csv"><i
|
||||
class="fa fa-download fa-fw"></i>下载用户信息文件模板</a> 进行编辑。
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -130,7 +147,8 @@
|
|||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
|
||||
class="fa fa-times-circle fa-fw"></i></button>
|
||||
<h3 data-field="dlg-title" class="modal-title"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -141,8 +159,12 @@
|
|||
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-sm btn-primary" data-field="btn-edit"><i class="fa fa-edit fa-fw"></i> 编辑用户信息</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 关闭</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" data-field="btn-edit"><i
|
||||
class="fa fa-edit fa-fw"></i> 编辑用户信息
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i
|
||||
class="fa fa-times fa-fw"></i> 关闭
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -152,7 +174,8 @@
|
|||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
|
||||
class="fa fa-times-circle fa-fw"></i></button>
|
||||
<h3 data-field="dlg-title" class="modal-title"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -169,7 +192,8 @@
|
|||
<div class="form-group form-group-sm">
|
||||
<label for="edit-user-username" class="col-sm-2 control-label require">账号:</label>
|
||||
<div class="col-sm-5">
|
||||
<input id="edit-user-username" type="text" class="form-control" placeholder="用户账号,也就是用户登录名"/>
|
||||
<input id="edit-user-username" type="text" class="form-control"
|
||||
placeholder="用户账号,也就是用户登录名"/>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="control-desc">英文字符和数字,最大32字符</div>
|
||||
|
@ -236,12 +260,16 @@
|
|||
## <li><div id="sec-auth-username-password" class="tp-checkbox">用户名 + 密码</div></li>
|
||||
|
||||
<li>
|
||||
<div id="sec-auth-username-password-captcha" class="tp-checkbox">用户名 + 密码 + 验证码</div>
|
||||
<div id="sec-auth-username-password-captcha" class="tp-checkbox">用户名 + 密码 +
|
||||
验证码
|
||||
</div>
|
||||
</li>
|
||||
## <li><div id="sec-auth-username-oath" class="tp-checkbox">用户名 + 身份认证器动态密码</div></li>
|
||||
|
||||
<li>
|
||||
<div id="sec-auth-username-password-oath" class="tp-checkbox">用户名 + 密码 + 身份认证器动态密码</div>
|
||||
<div id="sec-auth-username-password-oath" class="tp-checkbox">用户名 + 密码 +
|
||||
身份认证器动态密码
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -255,11 +283,16 @@
|
|||
<div class="modal-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div id="edit-user-message" class="alert alert-danger" style="text-align:left;display:none;"></div>
|
||||
<div id="edit-user-message" class="alert alert-danger"
|
||||
style="text-align:left;display:none;"></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-edit-user-save"><i class="fa fa-check fa-fw"></i> 确定</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-edit-user-save"><i
|
||||
class="fa fa-check fa-fw"></i> 确定
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i
|
||||
class="fa fa-times fa-fw"></i> 取消
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -271,7 +304,8 @@
|
|||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
|
||||
class="fa fa-times-circle fa-fw"></i></button>
|
||||
<h3 data-field="dlg-title" class="modal-title"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -287,8 +321,12 @@
|
|||
<div class="form-group form-group-sm">
|
||||
<div class="col-sm-10 col-sm-offset-1">
|
||||
<div id="can-send-email" style="display:none">
|
||||
<div> 向用户绑定的邮箱地址 <span data-field="email" class="mono"></span> 发送密码重置邮件,然后用户可通过邮件中的密码重置链接自行设置新密码。</div>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-send-reset-email" style="margin-top:10px;"><i class="fa fa-send fa-fw"></i> 发送邮件</button>
|
||||
<div> 向用户绑定的邮箱地址 <span data-field="email" class="mono"></span>
|
||||
发送密码重置邮件,然后用户可通过邮件中的密码重置链接自行设置新密码。
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-send-reset-email"
|
||||
style="margin-top:10px;"><i class="fa fa-send fa-fw"></i> 发送邮件
|
||||
</button>
|
||||
</div>
|
||||
<div id="cannot-send-email" class="alert alert-warning" style="margin-top:10px;">
|
||||
<i class="fas fa-exclamation-triangle fa-fw"></i> <span id="msg-cannot-send-email">用户未设置邮箱</span>,密码重置邮件功能无法使用,请使用手动重置方式。
|
||||
|
@ -316,18 +354,25 @@
|
|||
<div class="form-group form-group-sm">
|
||||
<div class="col-sm-5 col-sm-offset-1">
|
||||
<div class="input-group">
|
||||
<input data-field="password" type="password" class="form-control mono" placeholder="设置用户的新密码">
|
||||
<span class="input-group-btn"><button class="btn btn-sm btn-default" type="button" id="btn-switch-password"><i class="fa fa-eye fa-fw"></i></button></span>
|
||||
<input data-field="password" type="password" class="form-control mono"
|
||||
placeholder="设置用户的新密码">
|
||||
<span class="input-group-btn"><button class="btn btn-sm btn-default" type="button"
|
||||
id="btn-switch-password"><i
|
||||
class="fa fa-eye fa-fw"></i></button></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" class="btn btn-sm btn-info" id="btn-gen-random-password"><i class="far fa-snowflake fa-fw"></i> 生成随机密码</button>
|
||||
<button type="button" class="btn btn-sm btn-info" id="btn-gen-random-password"><i
|
||||
class="far fa-snowflake fa-fw"></i> 生成随机密码
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<div class="col-sm-6 col-sm-offset-1">
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-reset-password"><i class="fa fa-check fa-fw"></i> 重置密码</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-reset-password"><i
|
||||
class="fa fa-check fa-fw"></i> 重置密码
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -338,10 +383,13 @@
|
|||
<div class="modal-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div id="edit-user-message" class="alert alert-danger" style="text-align:left;display:none;"></div>
|
||||
<div id="edit-user-message" class="alert alert-danger"
|
||||
style="text-align:left;display:none;"></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i
|
||||
class="fa fa-times fa-fw"></i> 取消
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -353,24 +401,29 @@
|
|||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<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">导入用户</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div style="text-align:center;margin:10px 0 20px 0;">
|
||||
<p>请点击图标,选择要上传的文件!</p>
|
||||
<p><a href="/static/download/teleport-example-user.csv"><i class="fa fa-download fa-fw"></i>下载用户信息文件模板</a></p>
|
||||
<p><a href="/static/download/teleport-example-user.csv"><i class="fa fa-download fa-fw"></i>下载用户信息文件模板</a>
|
||||
</p>
|
||||
</div>
|
||||
<div style="text-align:center;">
|
||||
<i id="btn-select-file" class="upload-button far fa-file-alt fa-fw"></i>
|
||||
</div>
|
||||
<div style="text-align:center;margin:10px;" id="upload-file-info">- 尚未选择文件 -</div>
|
||||
<div style="text-align:center;">
|
||||
<div id="upload-file-message" style="display:none;margin:10px;text-align: left;" class="alert alert-info">
|
||||
<div id="upload-file-message" style="display:none;margin:10px;text-align: left;"
|
||||
class="alert alert-info">
|
||||
<i class="fa fa-cog fa-spin fa-fw"></i> 正在导入,请稍候...
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-do-upload-file" style="display:none;margin:10px;"><i class="fa fa-upload fa-fw"></i> 开始导入</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-do-upload-file"
|
||||
style="display:none;margin:10px;"><i class="fa fa-upload fa-fw"></i> 开始导入
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -381,7 +434,8 @@
|
|||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -391,31 +445,34 @@
|
|||
<div class="form-group form-group-sm">
|
||||
<label for="edit-ldap-server" class="col-sm-2 control-label require">LDAP主机:</label>
|
||||
<div class="col-sm-4">
|
||||
<input id="edit-ldap-server" type="text" class="form-control" placeholder="LDAP服务器IP或域名" />
|
||||
<input id="edit-ldap-server" type="text" class="form-control"
|
||||
placeholder="LDAP服务器IP或域名"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<label for="edit-ldap-port" class="col-sm-2 control-label require">端口:</label>
|
||||
<div class="col-sm-4">
|
||||
<input id="edit-ldap-port" type="text" class="form-control" placeholder="LDAP端口,默认为389" />
|
||||
<input id="edit-ldap-port" type="text" class="form-control"
|
||||
placeholder="LDAP端口,默认为389"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<label for="edit-ldap-domain" class="col-sm-2 control-label require">域:</label>
|
||||
<div class="col-sm-4">
|
||||
<input id="edit-ldap-domain" type="text" class="form-control" placeholder="" />
|
||||
<input id="edit-ldap-domain" type="text" class="form-control" placeholder=""/>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="control-desc-sm">LDAP的账号使用 <span class="important">用户名@域</span> 来登录teleport。</div>
|
||||
<div class="control-desc-sm">LDAP的账号使用 <span class="important">用户名@域</span> 来登录teleport。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<label for="edit-ldap-admin" class="col-sm-2 control-label require">管理员DN:</label>
|
||||
<div class="col-sm-4">
|
||||
<input id="edit-ldap-admin" type="text" class="form-control" placeholder="" />
|
||||
<input id="edit-ldap-admin" type="text" class="form-control" placeholder=""/>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="control-desc-sm">LDAP服务的管理员账号,用于列举用户、同步账号。</div>
|
||||
|
@ -426,8 +483,11 @@
|
|||
<label for="edit-ldap-password" class="col-sm-2 control-label require">密码:</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="input-group">
|
||||
<input id="edit-ldap-password" type="password" class="form-control mono" placeholder="" />
|
||||
<span class="input-group-btn"><button class="btn btn-sm btn-default" type="button" id="btn-switch-ldap-password"><i class="fa fa-eye fa-fw"></i></button></span>
|
||||
<input id="edit-ldap-password" type="password" class="form-control mono"
|
||||
placeholder=""/>
|
||||
<span class="input-group-btn"><button class="btn btn-sm btn-default" type="button"
|
||||
id="btn-switch-ldap-password"><i
|
||||
class="fa fa-eye fa-fw"></i></button></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
|
@ -444,24 +504,30 @@
|
|||
<div class="form-group form-group-sm">
|
||||
<label for="edit-ldap-base-dn" class="col-sm-2 control-label require">用户基准DN:</label>
|
||||
<div class="col-sm-9">
|
||||
<input id="edit-ldap-base-dn" type="text" class="form-control" placeholder="" />
|
||||
<div class="control-desc-sm">限制用户DN的范围,例如 <span class="important">ou=dev,ou=company,ou=com</span>。用户的完整DN为 <span class="important">cn=用户登录名,用户基准DN</span>。</div>
|
||||
<input id="edit-ldap-base-dn" type="text" class="form-control" placeholder=""/>
|
||||
<div class="control-desc-sm">限制用户DN的范围,例如 <span class="important">ou=dev,ou=company,ou=com</span>。用户的完整DN为
|
||||
<span class="important">cn=用户登录名,用户基准DN</span>。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<label for="edit-ldap-filter" class="col-sm-2 control-label require">过滤器:</label>
|
||||
<div class="col-sm-9">
|
||||
<input id="edit-ldap-filter" type="text" class="form-control" placeholder="" value="(&(objectClass=person))"/>
|
||||
<div class="control-desc-sm">列举用户时的过滤器,例如 <span class="important">(&(objectClass=person))</span>。</div>
|
||||
<input id="edit-ldap-filter" type="text" class="form-control" placeholder=""
|
||||
value="(&(objectClass=person))"/>
|
||||
<div class="control-desc-sm">列举用户时的过滤器,例如 <span class="important">(&(objectClass=person))</span>。
|
||||
</div>
|
||||
</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="">t</textarea>
|
||||
<div class="control-desc-sm">将LDAP的属性映射到 teleport 的用户属性,例如 <span class="important">LDAP中的用户属性 sAMAccountName 映射为teleport的登录账号</span>。如果不清楚此LDAP服务的用户属性,可使用下方的“列举属性”按钮进行查询。</div>
|
||||
<textarea id="edit-ldap-attr-map" class="form-control"
|
||||
style="resize:vertical;height:8em;" placeholder="">t</textarea>
|
||||
<div class="control-desc-sm">将LDAP的属性映射到 teleport 的用户属性,例如 <span class="important">LDAP中的用户属性 sAMAccountName 映射为teleport的登录账号</span>。如果不清楚此LDAP服务的用户属性,可使用下方的“列举属性”按钮进行查询。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -472,13 +538,22 @@
|
|||
<div class="modal-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div id="edit-user-message" class="alert alert-danger" style="text-align:left;display:none;"></div>
|
||||
<div id="edit-user-message" class="alert alert-danger"
|
||||
style="text-align:left;display:none;"></div>
|
||||
</div>
|
||||
<div class="col-sm-6" style="text-align:right;">
|
||||
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-config-list-attr"><i class="fa fa-list-alt fa-fw"></i> 列举属性</button>
|
||||
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-config-test"><i class="fa fa-bolt fa-fw"></i> 测试获取用户</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-ldap-config-save"><i class="fa fa-check fa-fw"></i> 保存设置</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-config-list-attr"><i
|
||||
class="fa fa-list-alt fa-fw"></i> 列举属性
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-config-test"><i
|
||||
class="fa fa-bolt fa-fw"></i> 测试获取用户
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-ldap-config-save"><i
|
||||
class="fa fa-check fa-fw"></i> 保存设置
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i
|
||||
class="fa fa-times fa-fw"></i> 取消
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -490,7 +565,8 @@
|
|||
<div class="modal-dialog" style="margin-top:50px;">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -503,7 +579,8 @@
|
|||
<div class="form-group form-group-sm">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div id="msg-ldap-list-attr-ret" style="height:20em;overflow:scroll;padding:5px;border: 1px solid #747474;"></div>
|
||||
<div id="msg-ldap-list-attr-ret"
|
||||
style="height:20em;overflow:scroll;padding:5px;border: 1px solid #747474;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -514,7 +591,9 @@
|
|||
<div class="modal-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal"><i class="fa fa-check fa-fw"></i> 确定</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal"><i
|
||||
class="fa fa-check fa-fw"></i> 确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -526,7 +605,8 @@
|
|||
<div class="modal-dialog" style="margin-top:50px;">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -539,7 +619,8 @@
|
|||
<div class="form-group form-group-sm">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<table id="table-ldap-test-ret" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
<table id="table-ldap-test-ret"
|
||||
class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -550,7 +631,9 @@
|
|||
<div class="modal-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal"><i class="fa fa-check fa-fw"></i> 确定</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal"><i
|
||||
class="fa fa-check fa-fw"></i> 确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -562,33 +645,61 @@
|
|||
<div class="modal-dialog modal-lg" style="margin-top:50px;">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="form-horizontal">
|
||||
<div style="margin-bottom:8px;">
|
||||
LDAP用户列表:
|
||||
<div class="table-prefix-area">
|
||||
<div class="table-extend-cell">
|
||||
<span class="table-name"><i class="fa fa-list fa-fw"></i> LDAP用户列表</span>
|
||||
<button id="btn-ldap-import-refresh" class="btn btn-sm btn-default"><i class="fa fa-redo fa-fw"></i> 刷新列表</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<table id="table-ldap-import" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
<table id="table-ldap-user-list"
|
||||
class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
|
||||
<div class="table-extend-area">
|
||||
<div class="table-extend-cell checkbox-select-all">
|
||||
<input id="table-ldap-user-select-all" type="checkbox"/>
|
||||
</div>
|
||||
<div class="table-extend-cell group-actions">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="btn-ldap-import-import" type="button" class="btn btn-primary">
|
||||
<i class="fas fa-address-book fa-fw"></i> 导入选中的用户
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## <div class="form-horizontal">
|
||||
## <div style="margin-bottom:8px;">
|
||||
## LDAP用户列表:
|
||||
## </div>
|
||||
##
|
||||
## <div class="form-group form-group-sm">
|
||||
##
|
||||
## <div class="col-sm-12">
|
||||
## <table id="table-ldap-user-list"
|
||||
## class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||
## </div>
|
||||
##
|
||||
## </div>
|
||||
##
|
||||
## </div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12" style="text-align:right;">
|
||||
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-import-refresh"><i class="fa fa-redo fa-fw"></i> 刷新列表</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" id="btn-ldap-import-import"><i class="fa fa-check fa-fw"></i> 导入选中用户</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal">
|
||||
<i class="fa fa-times fa-fw"></i> 关闭
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,13 @@ TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH
|
|||
APP_MODE_NORMAL = 1
|
||||
APP_MODE_MAINTENANCE = 2
|
||||
|
||||
# ==========================================================================
|
||||
# 用户类型
|
||||
# ==========================================================================
|
||||
TP_USER_TYPE_NONE = 0
|
||||
TP_USER_TYPE_LOCAL = 1
|
||||
TP_USER_TYPE_LDAP = 2
|
||||
|
||||
# ==========================================================================
|
||||
# 远程主机账号认证方式
|
||||
# ==========================================================================
|
||||
|
|
|
@ -258,6 +258,9 @@ controllers = [
|
|||
(r'/system/do-ldap-config-test', system.DoLdapConfigTestHandler),
|
||||
# - [json] 获取LDAP用户列表
|
||||
(r'/system/do-ldap-get-users', system.DoLdapGetUsersHandler),
|
||||
# - [json] 导入LDAP用户
|
||||
(r'/system/do-ldap-import', system.DoLdapImportHandler),
|
||||
|
||||
#
|
||||
# - [json] 获取服务器时间
|
||||
(r'/system/get-time', system.DoGetTimeHandler),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
|
||||
|
@ -17,6 +18,7 @@ from app.model import syslog
|
|||
from app.model import record
|
||||
from app.model import ops
|
||||
from app.model import audit
|
||||
from app.model import user
|
||||
from app.base.core_server import core_service_async_post_http
|
||||
from app.base.session import tp_session
|
||||
from app.logic.auth.ldap import Ldap
|
||||
|
@ -515,7 +517,7 @@ class DoLdapGetUsersHandler(TPBaseJsonHandler):
|
|||
|
||||
try:
|
||||
if len(tp_cfg().sys_ldap_password) == 0:
|
||||
return self.write_json(TPE_PARAM, message='需要设置LDAP管理员密码')
|
||||
return self.write_json(TPE_PARAM, message='LDAP未能正确配置,需要管理员密码')
|
||||
else:
|
||||
_password = tp_cfg().sys_ldap_password
|
||||
_server = tp_cfg().sys.ldap.server
|
||||
|
@ -535,14 +537,180 @@ class DoLdapGetUsersHandler(TPBaseJsonHandler):
|
|||
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:
|
||||
data[u]['bind'] = False
|
||||
return self.write_json(ret, data=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)
|
||||
except:
|
||||
log.e('')
|
||||
return self.write_json(TPE_PARAM)
|
||||
|
||||
|
||||
class DoLdapImportHandler(TPBaseJsonHandler):
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
|
||||
if ret != TPE_OK:
|
||||
return
|
||||
|
||||
args = self.get_argument('args', None)
|
||||
if args is None:
|
||||
return self.write_json(TPE_PARAM)
|
||||
try:
|
||||
args = json.loads(args)
|
||||
except:
|
||||
return self.write_json(TPE_JSON_FORMAT)
|
||||
|
||||
try:
|
||||
dn_hash_list = args['ldap_users']
|
||||
|
||||
if len(tp_cfg().sys_ldap_password) == 0:
|
||||
return self.write_json(TPE_PARAM, message='LDAP未能正确配置,需要管理员密码')
|
||||
else:
|
||||
_password = tp_cfg().sys_ldap_password
|
||||
_server = tp_cfg().sys.ldap.server
|
||||
_port = tp_cfg().sys.ldap.port
|
||||
_admin = tp_cfg().sys.ldap.admin
|
||||
_base_dn = tp_cfg().sys.ldap.base_dn
|
||||
_filter = tp_cfg().sys.ldap.filter
|
||||
_attr_map = tp_cfg().sys.ldap.attr_map
|
||||
except:
|
||||
return self.write_json(TPE_PARAM)
|
||||
|
||||
try:
|
||||
ldap = Ldap(_server, _port, _base_dn)
|
||||
ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_map)
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
def _do_import(self, users):
|
||||
success = list()
|
||||
failed = list()
|
||||
try:
|
||||
user_list = []
|
||||
for _u in users:
|
||||
u = dict()
|
||||
u['_line'] = 0
|
||||
u['_id'] = 0
|
||||
u['type'] = TP_USER_TYPE_LDAP
|
||||
u['ldap_dn'] = _u['dn']
|
||||
u['username'] = '{}@{}'.format(_u['username'], tp_cfg().sys.ldap.domain)
|
||||
u['surname'] = _u['surname']
|
||||
u['email'] = _u['email']
|
||||
u['mobile'] = ''
|
||||
u['qq'] = ''
|
||||
u['wechat'] = ''
|
||||
u['desc'] = ''
|
||||
u['password'] = ''
|
||||
|
||||
# fix
|
||||
if len(u['surname']) == 0:
|
||||
u['surname'] = u['username']
|
||||
u['username'] = u['username'].lower()
|
||||
|
||||
user_list.append(u)
|
||||
|
||||
user.create_users(self, user_list, success, failed)
|
||||
|
||||
# 对于创建成功的用户,发送密码邮件函
|
||||
sys_smtp_password = tp_cfg().sys_smtp_password
|
||||
if len(sys_smtp_password) > 0:
|
||||
web_url = '{}://{}'.format(self.request.protocol, self.request.host)
|
||||
for u in user_list:
|
||||
if u['_id'] == 0 or len(u['email']) == 0:
|
||||
continue
|
||||
|
||||
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)
|
||||
|
||||
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='用户密码函'
|
||||
# )
|
||||
if err != TPE_OK:
|
||||
failed.append({'line': u['_line'], 'error': '无法发送密码函到邮箱 {},错误:{}。'.format(u['email'], msg)})
|
||||
|
||||
# 统计结果
|
||||
total_success = 0
|
||||
total_failed = 0
|
||||
for u in user_list:
|
||||
if u['_id'] == 0:
|
||||
total_failed += 1
|
||||
else:
|
||||
total_success += 1
|
||||
|
||||
# 生成最终结果信息
|
||||
if len(failed) == 0:
|
||||
# ret['code'] = TPE_OK
|
||||
# ret['message'] = '共导入 {} 个用户账号!'.format(total_success)
|
||||
return self.write_json(TPE_OK, message='共导入 {} 个用户账号!'.format(total_success))
|
||||
else:
|
||||
# ret['code'] = TPE_FAILED
|
||||
msg = ''
|
||||
if total_success > 0:
|
||||
msg = '{} 个用户账号导入成功,'.format(total_success)
|
||||
if total_failed > 0:
|
||||
msg += '{} 个用户账号未能导入!'.format(total_failed)
|
||||
|
||||
# ret['data'] = failed
|
||||
return self.write_json(TPE_FAILED, data=failed, message=msg)
|
||||
|
||||
except:
|
||||
log.e('got exception when import LDAP user.\n')
|
||||
# ret['code'] = TPE_FAILED
|
||||
msg = ''
|
||||
if len(success) > 0:
|
||||
msg += '{} 个用户账号导入后发生异常!'.format(len(success))
|
||||
else:
|
||||
msg = '发生异常!'
|
||||
|
||||
# ret['data'] = failed
|
||||
return self.write_json(TPE_FAILED, data=failed, message=msg)
|
||||
|
||||
|
||||
class DoCleanupStorageHandler(TPBaseJsonHandler):
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
|
@ -573,5 +741,3 @@ class DoRebuildAuditAuzMapHandler(TPBaseJsonHandler):
|
|||
|
||||
err = ops.build_auz_map()
|
||||
self.write_json(err)
|
||||
|
||||
|
||||
|
|
|
@ -194,6 +194,10 @@ def create_users(handler, user_list, success, failed):
|
|||
|
||||
for i in range(len(user_list)):
|
||||
user = user_list[i]
|
||||
if 'type' not in user:
|
||||
user['type'] = TP_USER_TYPE_LOCAL
|
||||
if 'ldap_dn' not in user:
|
||||
user['ldap_dn'] = ''
|
||||
|
||||
err = s.reset().select_from('user', ['id']).where('user.username="{}"'.format(user['username'])).query()
|
||||
if err != TPE_OK:
|
||||
|
@ -202,11 +206,14 @@ def create_users(handler, user_list, success, failed):
|
|||
failed.append({'line': user['_line'], 'error': '账号 `{}` 已经存在'.format(user['username'])})
|
||||
continue
|
||||
|
||||
_password = tp_password_generate_secret(user['password'])
|
||||
if user['type'] == TP_USER_TYPE_LOCAL:
|
||||
_password = tp_password_generate_secret(user['password'])
|
||||
else:
|
||||
_password = ''
|
||||
|
||||
sql = 'INSERT INTO `{}user` (`type`, `auth_type`, `password`, `username`, `surname`, `role_id`, `state`, `email`, `creator_id`, `create_time`, `last_login`, `last_chpass`, `desc`) VALUES ' \
|
||||
'(1, 0, "{password}", "{username}", "{surname}", 0, {state}, "{email}", {creator_id}, {create_time}, {last_login}, {last_chpass}, "{desc}");' \
|
||||
''.format(db.table_prefix,
|
||||
'({user_type}, 0, "{password}", "{username}", "{surname}", 0, {state}, "{email}", {creator_id}, {create_time}, {last_login}, {last_chpass}, "{desc}");' \
|
||||
''.format(db.table_prefix, user_type=user['type'],
|
||||
username=user['username'], surname=user['surname'], password=_password, state=TP_STATE_NORMAL, email=user['email'],
|
||||
creator_id=operator['id'], create_time=_time_now, last_login=0, last_chpass=0, desc=user['desc'])
|
||||
db_ret = db.exec(sql)
|
||||
|
|
Loading…
Reference in New Issue