Commit 4bc5eced authored by ibuler's avatar ibuler

Merge branch 'dev' of github.com:jumpserver/jumpserver into dev

parents bf7079df b82a66c8
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-27 12:48+0800\n"
"POT-Creation-Date: 2019-03-28 12:41+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
......@@ -165,7 +165,7 @@ msgstr "SSH网关,支持代理SSH,RDP和VNC"
#: perms/templates/perms/asset_permission_list.html:53
#: perms/templates/perms/asset_permission_list.html:72
#: perms/templates/perms/asset_permission_user.html:54 settings/models.py:29
#: settings/templates/settings/_ldap_list_users_modal.html:35
#: settings/templates/settings/_ldap_list_users_modal.html:38
#: settings/templates/settings/command_storage_create.html:41
#: settings/templates/settings/replay_storage_create.html:44
#: settings/templates/settings/terminal_setting.html:80
......@@ -207,7 +207,7 @@ msgstr "名称"
#: authentication/templates/authentication/new_login.html:90
#: ops/models/adhoc.py:164 perms/templates/perms/asset_permission_list.html:74
#: perms/templates/perms/asset_permission_user.html:55
#: settings/templates/settings/_ldap_list_users_modal.html:34 users/forms.py:13
#: settings/templates/settings/_ldap_list_users_modal.html:37 users/forms.py:13
#: users/models/user.py:52 users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:67
#: users/templates/users/user_list.html:24
......@@ -1025,8 +1025,8 @@ msgstr "其它"
#: settings/templates/settings/basic_setting.html:61
#: settings/templates/settings/command_storage_create.html:79
#: settings/templates/settings/email_setting.html:62
#: settings/templates/settings/ldap_setting.html:62
#: settings/templates/settings/replay_storage_create.html:152
#: settings/templates/settings/ldap_setting.html:61
#: settings/templates/settings/replay_storage_create.html:151
#: settings/templates/settings/security_setting.html:70
#: settings/templates/settings/terminal_setting.html:68
#: terminal/templates/terminal/terminal_update.html:45
......@@ -1061,8 +1061,8 @@ msgstr "重置"
#: settings/templates/settings/basic_setting.html:62
#: settings/templates/settings/command_storage_create.html:80
#: settings/templates/settings/email_setting.html:63
#: settings/templates/settings/ldap_setting.html:63
#: settings/templates/settings/replay_storage_create.html:153
#: settings/templates/settings/ldap_setting.html:64
#: settings/templates/settings/replay_storage_create.html:152
#: settings/templates/settings/security_setting.html:71
#: settings/templates/settings/terminal_setting.html:70
#: terminal/templates/terminal/command_list.html:103
......@@ -1087,7 +1087,8 @@ msgid "Asset detail"
msgstr "资产详情"
#: assets/templates/assets/_user_asset_detail_modal.html:23
#: templates/_modal.html:21
#: settings/templates/settings/_ldap_list_users_modal.html:96
#: templates/_modal.html:22
msgid "Close"
msgstr "关闭"
......@@ -1259,7 +1260,7 @@ msgstr "选择节点"
#: assets/templates/assets/system_user_detail.html:182
#: assets/templates/assets/system_user_list.html:143
#: settings/templates/settings/terminal_setting.html:165
#: templates/_modal.html:22 terminal/templates/terminal/session_detail.html:108
#: templates/_modal.html:23 terminal/templates/terminal/session_detail.html:108
#: users/templates/users/user_detail.html:388
#: users/templates/users/user_detail.html:414
#: users/templates/users/user_detail.html:437
......@@ -1392,6 +1393,7 @@ msgid "Create asset"
msgstr "创建资产"
#: assets/templates/assets/asset_list.html:73
#: settings/templates/settings/_ldap_list_users_modal.html:97
#: users/templates/users/user_list.html:7
#: xpack/plugins/license/templates/license/license_detail.html:101
msgid "Import"
......@@ -1611,7 +1613,7 @@ msgstr "创建网关"
#: assets/templates/assets/domain_gateway_list.html:99
#: assets/templates/assets/domain_gateway_list.html:101
#: settings/templates/settings/email_setting.html:61
#: settings/templates/settings/ldap_setting.html:61
#: settings/templates/settings/ldap_setting.html:62
msgid "Test connection"
msgstr "测试连接"
......@@ -2834,38 +2836,33 @@ msgstr "资产授权用户列表"
msgid "Asset permission asset list"
msgstr "资产授权资产列表"
#: settings/api.py:23
#: settings/api.py:26
msgid "Test mail sent to {}, please check"
msgstr "邮件已经发送{}, 请检查"
#: settings/api.py:47
#: settings/api.py:50
msgid "Test ldap success"
msgstr "连接LDAP成功"
#: settings/api.py:77 settings/utils.py:23
msgid "Search no entry matched in ou {}"
msgstr "在ou:{}中没有匹配条目"
#: settings/api.py:86
#: settings/api.py:87
msgid "Match {} s users"
msgstr "匹配 {} 个用户"
#: settings/api.py:109
msgid ""
"User is not currently selected, please check the user you want to import"
msgstr "当前无勾选用户,请勾选你想要导入的用户"
#: settings/api.py:120
msgid "succeed: {} failed: {} total: {}"
msgstr "成功:{} 失败:{} 总数:{}"
#: settings/api.py:139 settings/api.py:175
#: settings/api.py:142 settings/api.py:178
msgid ""
"Error: Account invalid (Please make sure the information such as Access key "
"or Secret key is correct)"
msgstr "错误:账户无效 (请确保 Access key 或 Secret key 等信息正确)"
#: settings/api.py:145 settings/api.py:181
#: settings/api.py:148 settings/api.py:184
msgid "Create succeed"
msgstr "创建成功"
#: settings/api.py:163 settings/api.py:201
#: settings/api.py:166 settings/api.py:204
#: settings/templates/settings/terminal_setting.html:151
msgid "Delete succeed"
msgstr "删除成功"
......@@ -3108,24 +3105,28 @@ msgid ""
"characters"
msgstr "开启后,用户密码修改、重置必须包含特殊字符"
#: settings/models.py:126 users/templates/users/reset_password.html:68
#: settings/models.py:128 users/templates/users/reset_password.html:68
#: users/templates/users/user_profile.html:20
msgid "Setting"
msgstr "设置"
#: settings/templates/settings/_ldap_list_users_modal.html:7
msgid "Ldap users"
msgstr "Ldap 用户列表"
msgid "LDAP user list"
msgstr "LDAP 用户列表"
#: settings/templates/settings/_ldap_list_users_modal.html:9
msgid "Please submit the LDAP configuration before import"
msgstr "请先提交LDAP配置再进行导入"
#: settings/templates/settings/_ldap_list_users_modal.html:36
#: settings/templates/settings/_ldap_list_users_modal.html:39
#: users/models/user.py:56 users/templates/users/user_detail.html:71
#: users/templates/users/user_profile.html:59
msgid "Email"
msgstr "邮件"
#: settings/templates/settings/_ldap_list_users_modal.html:37
msgid "Is imported"
msgstr "是否已经导入"
#: settings/templates/settings/_ldap_list_users_modal.html:40
msgid "Existing"
msgstr "已存在"
#: settings/templates/settings/basic_setting.html:15
#: settings/templates/settings/email_setting.html:15
......@@ -3182,8 +3183,13 @@ msgid "Doc type"
msgstr "文档类型"
#: settings/templates/settings/ldap_setting.html:65
msgid "Sync User"
msgstr "同步用户"
msgid "Bulk import"
msgstr "一键导入"
#: settings/templates/settings/ldap_setting.html:116
msgid ""
"User is not currently selected, please check the user you want to import"
msgstr "当前无勾选用户,请勾选你想要导入的用户"
#: settings/templates/settings/replay_storage_create.html:66
msgid "Bucket"
......@@ -3289,44 +3295,17 @@ msgstr "删除失败"
msgid "Are you sure about deleting it?"
msgstr "您确定删除吗?"
#: settings/utils.py:30
msgid "Have user but attr mapping error"
msgstr "有用户但attr映射错误"
#: settings/utils.py:60
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:86
msgid "No"
msgstr "否"
#: settings/utils.py:69
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:84
msgid "Yes"
msgstr "是"
#: settings/utils.py:137
msgid ""
"Import {} users successfully; import {} users failed, the database already "
"exists with the same name"
msgstr "导入 {} 个用户成功; 导入 {} 这些用户失败,数据库已经存在同名的用户"
#: settings/utils.py:142
msgid ""
"Import {} users successfully; import {} users failed, the database already "
"exists with the same name; import {}users failed, Because’TypeError' object "
"has no attribute 'keys'"
msgstr ""
"导入 {} 个用户成功; 导入 {} 这些用户失败,数据库已经存在同名的用户; 导入 {} "
"这些用户失败,因为对象没有属性'keys'"
msgid "User does not exist"
msgstr "用户不存在"
#: settings/utils.py:148
msgid "Import {} users successfully"
msgstr "导入 {} 个用户成功"
#: settings/utils.py:72
msgid "The user source is not LDAP"
msgstr "用户来源不是LDAP"
#: settings/utils.py:151
msgid ""
"Import {} users successfully;import {} users failed, Because’TypeError' "
"object has no attribute 'keys'"
msgstr "导入 {} 个用户成功; 导入 {} 这些用户失败,因为对象没有属性'keys'"
#: settings/utils.py:146
msgid "Search no entry matched in ou {}"
msgstr "在ou:{}中没有匹配条目"
#: settings/views.py:18 settings/views.py:44 settings/views.py:70
#: settings/views.py:99 settings/views.py:126 settings/views.py:138
......@@ -4920,6 +4899,14 @@ msgstr "更改资产上的用户密码时,将会使用与该资产关联的管
msgid "Length"
msgstr "长度"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:84
msgid "Yes"
msgstr "是"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:86
msgid "No"
msgstr "否"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:134
msgid "Run plan manually"
msgstr "手动执行计划"
......@@ -5369,6 +5356,33 @@ msgstr "创建组织"
msgid "Update org"
msgstr "更新组织"
#~ msgid "Sync User"
#~ msgstr "同步用户"
#~ msgid "Have user but attr mapping error"
#~ msgstr "有用户但attr映射错误"
#~ msgid ""
#~ "Import {} users successfully; import {} users failed, the database "
#~ "already exists with the same name"
#~ msgstr "导入 {} 个用户成功; 导入 {} 这些用户失败,数据库已经存在同名的用户"
#~ msgid ""
#~ "Import {} users successfully; import {} users failed, the database "
#~ "already exists with the same name; import {}users failed, "
#~ "Because’TypeError' object has no attribute 'keys'"
#~ msgstr ""
#~ "导入 {} 个用户成功; 导入 {} 这些用户失败,数据库已经存在同名的用户; 导入 "
#~ "{} 这些用户失败,因为对象没有属性'keys'"
#~ msgid "Import {} users successfully"
#~ msgstr "导入 {} 个用户成功"
#~ msgid ""
#~ "Import {} users successfully;import {} users failed, Because’TypeError' "
#~ "object has no attribute 'keys'"
#~ msgstr "导入 {} 个用户成功; 导入 {} 这些用户失败,因为对象没有属性'keys'"
#~ msgid "Monitor"
#~ msgstr "监控"
......
......@@ -5,18 +5,21 @@ import os
import json
import jms_storage
from ldap3 import Server, Connection
from rest_framework.views import Response, APIView
from django.conf import settings
from django.core.mail import send_mail
from django.utils.translation import ugettext_lazy as _
from .models import Setting
from .utils import get_ldap_users_list, save_user
from .utils import LDAPUtil
from common.permissions import IsOrgAdmin, IsSuperUser
from common.utils import get_logger
from .serializers import MailTestSerializer, LDAPTestSerializer
logger = get_logger(__file__)
class MailTestingAPI(APIView):
permission_classes = (IsOrgAdmin,)
serializer_class = MailTestSerializer
......@@ -46,78 +49,78 @@ class LDAPTestingAPI(APIView):
serializer_class = LDAPTestSerializer
success_message = _("Test ldap success")
@staticmethod
def get_ldap_util(serializer):
host = serializer.validated_data["AUTH_LDAP_SERVER_URI"]
bind_dn = serializer.validated_data["AUTH_LDAP_BIND_DN"]
password = serializer.validated_data["AUTH_LDAP_BIND_PASSWORD"]
use_ssl = serializer.validated_data.get("AUTH_LDAP_START_TLS", False)
search_ougroup = serializer.validated_data["AUTH_LDAP_SEARCH_OU"]
search_filter = serializer.validated_data["AUTH_LDAP_SEARCH_FILTER"]
attr_map = serializer.validated_data["AUTH_LDAP_USER_ATTR_MAP"]
try:
attr_map = json.loads(attr_map)
except json.JSONDecodeError:
return Response({"error": "AUTH_LDAP_USER_ATTR_MAP not valid"}, status=401)
util = LDAPUtil(
use_settings_config=False, server_uri=host, bind_dn=bind_dn,
password=password, use_ssl=use_ssl,
search_ougroup=search_ougroup, search_filter=search_filter,
attr_map=attr_map
)
return util
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
host = serializer.validated_data["AUTH_LDAP_SERVER_URI"]
bind_dn = serializer.validated_data["AUTH_LDAP_BIND_DN"]
password = serializer.validated_data["AUTH_LDAP_BIND_PASSWORD"]
use_ssl = serializer.validated_data.get("AUTH_LDAP_START_TLS", False)
search_ougroup = serializer.validated_data["AUTH_LDAP_SEARCH_OU"]
search_filter = serializer.validated_data["AUTH_LDAP_SEARCH_FILTER"]
attr_map = serializer.validated_data["AUTH_LDAP_USER_ATTR_MAP"]
if not serializer.is_valid():
return Response({"error": str(serializer.errors)}, status=401)
try:
attr_map = json.loads(attr_map)
except json.JSONDecodeError:
return Response({"error": "AUTH_LDAP_USER_ATTR_MAP not valid"}, status=401)
util = self.get_ldap_util(serializer)
server = Server(host, use_ssl=use_ssl)
conn = Connection(server, bind_dn, password)
try:
conn.bind()
except Exception as e:
return Response({"error": str(e)}, status=401)
try:
users = util.get_search_user_items()
except Exception as e:
return Response({"error": str(e)}, status=401)
users = []
for search_ou in str(search_ougroup).split("|"):
ok = conn.search(search_ou, search_filter % ({"user": "*"}),
attributes=list(attr_map.values()))
if not ok:
return Response({"error": _("Search no entry matched in ou {}").format(search_ou)}, status=401)
for entry in conn.entries:
user = {}
for attr, mapping in attr_map.items():
if hasattr(entry, mapping):
user[attr] = getattr(entry, mapping)
users.append(user)
if len(users) > 0:
return Response({"msg": _("Match {} s users").format(len(users))})
else:
return Response({"error": "Have user but attr mapping error"}, status=401)
if len(users) > 0:
return Response({"msg": _("Match {} s users").format(len(users))})
else:
return Response({"error": str(serializer.errors)}, status=401)
return Response({"error": "Have user but attr mapping error"}, status=401)
class LDAPSyncAPI(APIView):
class LDAPUserListApi(APIView):
permission_classes = (IsOrgAdmin,)
def get(self, request):
ldap_users_list = get_ldap_users_list()
if not isinstance(ldap_users_list, list):
return Response(ldap_users_list, status=401)
return Response(ldap_users_list)
util = LDAPUtil()
try:
users = util.get_search_user_items()
except Exception as e:
users = []
logger.error(e, exc_info=True)
else:
users = sorted(users, key=lambda u: (u['existing'], u['username']))
return Response(users)
class LDAPConfirmSyncAPI(APIView):
class LDAPUserSyncAPI(APIView):
permission_classes = (IsOrgAdmin,)
def post(self, request):
user_names = request.data.get('user_names', '')
if not user_names:
error = _('User is not currently selected, please check the user '
'you want to import')
return Response({'error': error}, status=401)
ldap_users_list = get_ldap_users_list(user_names=user_names)
if not isinstance(ldap_users_list, list):
return Response(ldap_users_list, status=401)
save_result = save_user(ldap_users_list)
if 'error' in save_result.keys():
return Response(save_result, status=401)
return Response(save_result)
util = LDAPUtil()
try:
result = util.sync_users(username_set=user_names)
except Exception as e:
logger.error(e, exc_info=True)
return Response({'error': str(e)}, status=401)
else:
msg = _("succeed: {} failed: {} total: {}").format(
result['succeed'], result['failed'], result['total']
)
return Response({'msg': msg})
class ReplayStorageCreateAPI(APIView):
......
......@@ -79,6 +79,8 @@ class Setting(models.Model):
obj.cleaned_value = data
else:
value = obj.cleaned_value
if value is None:
value = {}
value.update(data)
obj.cleaned_value = value
obj.save()
......
......@@ -4,7 +4,10 @@
{% block modal_class %}modal-lg{% endblock %}
{% block modal_id %}ldap_list_users_modal{% endblock %}
{% block modal_title%}{% trans "Ldap users" %}{% endblock %}
{% block modal_title%}{% trans "LDAP user list" %}{% endblock %}
{% block modal_help_message%} <div class="alert alert-info help-message" style="width: 838px; margin-left: 30px">{% trans 'Please submit the LDAP configuration before import' %}</div>{% endblock %}
{% block modal_body %}
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
......@@ -34,7 +37,7 @@
<th class="text-center">{% trans 'Username' %}</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Email' %}</th>
<th class="text-center">{% trans 'Is imported' %}</th>
<th class="text-center">{% trans 'Existing' %}</th>
</tr>
</thead>
<tbody>
......@@ -47,16 +50,25 @@
<script>
var ldap_users_table = 0;
function initLdapTable() {
function initLdapUsersTable() {
if(ldap_users_table){
return
}
var options = {
ele: $('#ldap_list_users_table'),
ajax_url: '{% url "api-settings:ldap-sync" %}',
ajax_url: '{% url "api-settings:ldap-user-list" %}',
columnDefs: [
{targets: 4, createdCell: function (td, cellData, rowData) {
if(cellData){
$(td).html('<i class="fa fa-check text-navy"></i>')
}else{
$(td).html('<i class="fa fa-times text-danger"></i>')
}
}}
],
columns: [
{data: "username" },{data: "username" }, {data: "name" },
{data:"email"}, {data:'is_imported'}
{data:"email"}, {data:'existing'}
],
pageLength: 10
};
......@@ -68,8 +80,7 @@ function initLdapTable() {
$(document).ready(function(){
}).on('show.bs.modal', function () {
initLdapTable();
initLdapUsersTable();
})
.on('click','.close_btn1',function () {
window.location.reload()
......@@ -82,9 +93,9 @@ $(document).ready(function(){
{% endblock %}
{% block modal_button %}
{{ block.super }}
<button data-dismiss="modal" class="btn btn-white close_btn2" type="button">{% trans "Close" %}</button>
<button class="btn btn-primary" type="button" id="{% block modal_confirm_id %}btn_ldap_modal_confirm{% endblock %}">{% trans 'Import' %}</button>
{% endblock %}
{% block modal_confirm_id %}btn_ldap_modal_confirm{% endblock %}
......@@ -58,11 +58,11 @@
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-default btn-test" type="button"> {% trans 'Test connection' %}</button>
<button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
<button class="btn btn-default btn-test" type="button"> {% trans 'Test connection' %}</button>
{# <button class="btn btn-primary sync_button " data-toggle="modal" data-target="#sync_users_modal" type="button">{% trans 'Synchronization' %}</button>#}
<button class="btn btn-primary sync_button " data-toggle="modal" data-target="#ldap_list_users_modal" type="button">{% trans 'Sync User' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
<button class="btn btn-default sync_button " data-toggle="modal" data-target="#ldap_list_users_modal" type="button">{% trans 'Bulk import' %}</button>
</div>
</div>
</form>
......@@ -108,11 +108,17 @@ $(document).ready(function () {
})
.on("click","#btn_ldap_modal_confirm",function () {
var user_names=[];
var cheked = $("tbody input[type='checkbox']:checked").each(function () {
$("tbody input[type='checkbox']:checked").each(function () {
user_names.push($(this).attr('id'));
});
var the_url = "{% url "api-settings:ldap-comfirm-sync" %}";
if (user_names.length === 0){
var msg = "{% trans 'User is not currently selected, please check the user you want to import'%}"
toastr.error(msg);
return
}
var the_url = "{% url "api-settings:ldap-user-sync" %}";
function error(message) {
toastr.error(message)
......
......@@ -9,8 +9,8 @@ app_name = 'common'
urlpatterns = [
path('mail/testing/', api.MailTestingAPI.as_view(), name='mail-testing'),
path('ldap/testing/', api.LDAPTestingAPI.as_view(), name='ldap-testing'),
path('ldap/sync/', api.LDAPSyncAPI.as_view(), name='ldap-sync'),
path('ldap/comfirm/sync/', api.LDAPConfirmSyncAPI.as_view(), name='ldap-comfirm-sync'),
path('ldap/users/', api.LDAPUserListApi.as_view(), name='ldap-user-list'),
path('ldap/users/sync/', api.LDAPUserSyncAPI.as_view(), name='ldap-user-sync'),
path('terminal/replay-storage/create/', api.ReplayStorageCreateAPI.as_view(), name='replay-storage-create'),
path('terminal/replay-storage/delete/', api.ReplayStorageDeleteAPI.as_view(), name='replay-storage-delete'),
path('terminal/command-storage/create/', api.CommandStorageCreateAPI.as_view(), name='command-storage-create'),
......
......@@ -4,151 +4,159 @@
from ldap3 import Server, Connection
from django.utils.translation import ugettext_lazy as _
from .models import settings
from users.models import User
from common.utils import get_logger
from .models import settings
def ldap_conn(host, use_ssl, bind_dn, password):
server = Server(host, use_ssl=use_ssl)
conn = Connection(server, bind_dn, password)
return conn
logger = get_logger(__file__)
def ldap_search(conn, search_ougroup, search_filter, attr_map, user_names=None):
users_list = []
for search_ou in str(search_ougroup).split("|"):
ok = conn.search(search_ou, search_filter % ({"user": "*"}),
attributes=list(attr_map.values()))
if not ok:
error = _("Search no entry matched in ou {}").format(search_ou)
return {"error": error}
ldap_map_users(conn, attr_map, users_list, user_names)
class LDAPOUGroupException(Exception):
pass
if len(users_list) > 0:
return users_list
return {"error": _("Have user but attr mapping error")}
class LDAPUtil:
def get_ldap_users_list(user_names=None):
ldap_setting = get_ldap_setting()
conn = ldap_conn(ldap_setting['host'], ldap_setting['use_ssl'],
ldap_setting['bind_dn'], ldap_setting['password'])
try:
conn.bind()
except Exception as e:
return {"error": str(e)}
def __init__(self, use_settings_config=True, server_uri=None, bind_dn=None,
password=None, use_ssl=None, search_ougroup=None,
search_filter=None, attr_map=None, auth_ldap=None):
result_search = ldap_search(conn, ldap_setting['search_ougroup'],
ldap_setting['search_filter'],
ldap_setting['attr_map'], user_names=user_names)
return result_search
# config
if use_settings_config:
self._load_config_from_settings()
else:
self.server_uri = server_uri
self.bind_dn = bind_dn
self.password = password
self.use_ssl = use_ssl
self.search_ougroup = search_ougroup
self.search_filter = search_filter
self.attr_map = attr_map
self.auth_ldap = auth_ldap
def _load_config_from_settings(self):
self.server_uri = settings.AUTH_LDAP_SERVER_URI
self.bind_dn = settings.AUTH_LDAP_BIND_DN
self.password = settings.AUTH_LDAP_BIND_PASSWORD
self.use_ssl = settings.AUTH_LDAP_START_TLS
self.search_ougroup = settings.AUTH_LDAP_SEARCH_OU
self.search_filter = settings.AUTH_LDAP_SEARCH_FILTER
self.attr_map = settings.AUTH_LDAP_USER_ATTR_MAP
self.auth_ldap = settings.AUTH_LDAP
@staticmethod
def get_user_by_username(username):
try:
user = User.objects.get(username=username)
except Exception as e:
logger.info(e)
return None
else:
return user
@staticmethod
def _update_user(user, user_item):
for field, value in user_item.items():
if not hasattr(user, field):
continue
setattr(user, field, value)
user.save()
def ldap_map_users(conn, attr_map, users, user_names=None):
for entry in conn.entries:
user = entry_user(entry, attr_map)
if user_names:
if user.get('username', '') in user_names:
users.append(user)
else:
users.append(user)
def entry_user(entry, attr_map):
user = {}
user['is_imported'] = _('No')
for attr, mapping in attr_map.items():
if not hasattr(entry, mapping):
continue
value = getattr(entry, mapping).value
user[attr] = value if value else ''
if attr != 'username':
continue
if User.objects.filter(username=user[attr]):
user['is_imported'] = _('Yes')
return user
def get_ldap_setting():
host = settings.AUTH_LDAP_SERVER_URI
bind_dn = settings.AUTH_LDAP_BIND_DN
password = settings.AUTH_LDAP_BIND_PASSWORD
use_ssl = settings.AUTH_LDAP_START_TLS
search_ougroup = settings.AUTH_LDAP_SEARCH_OU
search_filter = settings.AUTH_LDAP_SEARCH_FILTER
attr_map = settings.AUTH_LDAP_USER_ATTR_MAP
auth_ldap = settings.AUTH_LDAP
ldap_setting = {
'host': host, 'bind_dn': bind_dn, 'password': password,
'search_ougroup': search_ougroup, 'search_filter': search_filter,
'attr_map': attr_map, 'auth_ldap': auth_ldap, 'use_ssl': use_ssl,
}
return ldap_setting
def save_user(users):
exist = []
username_list = [item.get('username') for item in users]
for name in username_list:
if User.objects.filter(username=name).exclude(source='ldap'):
exist.append(name)
users = [user for user in users if (user.get('username') not in exist)]
result_save = save(users, exist)
return result_save
def save(users, exist):
fail_user = []
for item in users:
item = set_default_item(item)
user = User.objects.filter(username=item['username'], source='ldap')
user = user.first()
def update_user(self, user_item):
user = self.get_user_by_username(user_item['username'])
if not user:
try:
user = User.objects.create(**item)
except Exception as e:
fail_user.append(item.get('username'))
msg = _('User does not exist')
return False, msg
if user.source != User.SOURCE_LDAP:
msg = _('The user source is not LDAP')
return False, msg
try:
self._update_user(user, user_item)
except Exception as e:
logger.error(e, exc_info=True)
return False, str(e)
else:
return True, None
@staticmethod
def create_user(user_item):
user_item['source'] = User.SOURCE_LDAP
try:
User.objects.create(**user_item)
except Exception as e:
logger.error(e, exc_info=True)
return False, str(e)
else:
return True, None
@staticmethod
def get_or_construct_email(user_item):
if not user_item.get('email', None):
if '@' in user_item['username']:
email = user_item['username']
else:
email = '{}@{}'.format(
user_item['username'], settings.EMAIL_SUFFIX)
else:
email = user_item['email']
return email
def create_or_update_users(self, user_items, force_update=True):
succeed = failed = 0
for user_item in user_items:
user_item['email'] = self.get_or_construct_email(user_item)
exist = user_item.pop('existing', None)
if exist:
ok, error = self.update_user(user_item)
else:
ok, error = self.create_user(user_item)
if not ok:
failed += 1
else:
succeed += 1
result = {'total': len(user_items), 'succeed': succeed, 'failed': failed}
return result
def _ldap_entry_to_user_item(self, entry):
user_item = {}
for attr, mapping in self.attr_map.items():
if not hasattr(entry, mapping):
continue
for key, value in item.items():
user.key = value
user.save()
get_msg = get_messages(users, exist, fail_user)
return get_msg
user_item[attr] = getattr(entry, mapping).value or ''
return user_item
def set_default_item(item):
item['source'] = 'ldap'
if not item.get('email', ''):
if '@' in item['username']:
item['email'] = item['username']
else:
item['email'] = item['username'] + '@' + settings.EMAIL_SUFFIX
if 'is_imported' in item.keys():
item.pop('is_imported')
return item
def get_messages(users, exist, fail_user):
if exist:
info = _("Import {} users successfully; import {} users failed, the "
"database already exists with the same name")
msg = info.format(len(users), str(exist))
if fail_user:
info = _("Import {} users successfully; import {} users failed, "
"the database already exists with the same name; import {}"
"users failed, Because’TypeError' object has no attribute "
"'keys'")
msg = info.format(len(users)-len(fail_user), str(exist), str(fail_user))
else:
msg = _("Import {} users successfully").format(len(users))
if fail_user:
info = _("Import {} users successfully;import {} users failed, "
"Because’TypeError' object has no attribute 'keys'")
msg = info.format(len(users)-len(fail_user), str(fail_user))
return {'msg': msg}
\ No newline at end of file
def get_connection(self):
server = Server(self.server_uri, use_ssl=self.use_ssl)
conn = Connection(server, self.bind_dn, self.password)
conn.bind()
return conn
def get_search_user_items(self):
conn = self.get_connection()
user_items = []
search_ougroup = str(self.search_ougroup).split("|")
for search_ou in search_ougroup:
ok = conn.search(
search_ou, self.search_filter % ({"user": "*"}),
attributes=list(self.attr_map.values())
)
if not ok:
error = _("Search no entry matched in ou {}".format(search_ou))
raise LDAPOUGroupException(error)
for entry in conn.entries:
user_item = self._ldap_entry_to_user_item(entry)
user = self.get_user_by_username(user_item['username'])
user_item['existing'] = bool(user)
user_items.append(user_item)
return user_items
def sync_users(self, username_set):
user_items = self.get_search_user_items()
if username_set:
user_items = [u for u in user_items if u['username'] in username_set]
result = self.create_or_update_users(user_items)
return result
......@@ -12,6 +12,7 @@
<h4 class="modal-title">{% block modal_title %}{% endblock %}</h4>
<small>{% block modal_comment %}{% endblock %}</small>
</div>
{% block modal_help_message %}{% endblock %}
<div class="modal-body">
{% block modal_body %}
{% endblock %}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment