-
Notifications
You must be signed in to change notification settings - Fork 370
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix get ldap users via ccnet_api (#5711)
* fix get ldap users via ccnet_api * improve code * optimize code
- Loading branch information
1 parent
3ed3dff
commit 5b17246
Showing
2 changed files
with
74 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
# Copyright (c) 2012-2016 Seafile Ltd. | ||
import os | ||
import json | ||
import logging | ||
from types import FunctionType | ||
from constance import config | ||
|
@@ -11,6 +10,7 @@ | |
from rest_framework.response import Response | ||
from rest_framework.views import APIView | ||
|
||
from django.db import connection | ||
from django.db.models import Q | ||
from django.core.cache import cache | ||
from django.utils.translation import gettext as _ | ||
|
@@ -25,7 +25,7 @@ | |
from seahub.api2.throttling import UserRateThrottle | ||
from seahub.api2.utils import api_error, to_python_boolean | ||
from seahub.api2.models import TokenV2 | ||
|
||
from seahub.utils.ccnet_db import get_ccnet_db_name | ||
import seahub.settings as settings | ||
from seahub.settings import SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, INIT_PASSWD, \ | ||
SEND_EMAIL_ON_RESETTING_USER_PASSWD | ||
|
@@ -98,10 +98,36 @@ | |
json_content_type = 'application/json; charset=utf-8' | ||
|
||
|
||
class LdapUser(object): | ||
def __init__(self, email, ctime): | ||
class UserObj(object): | ||
def __init__(self, email, ctime, is_staff, is_active, role): | ||
self.email = email | ||
self.ctime = ctime | ||
self.is_staff = is_staff | ||
self.is_active = is_active | ||
self.role = role | ||
|
||
|
||
def get_user_objs_from_ccnet(email_list): | ||
db_name, error_msg = get_ccnet_db_name() | ||
if error_msg: | ||
logger.error(error_msg) | ||
return list(), api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') | ||
|
||
sql = """SELECT e.email, is_staff, is_active, ctime, role FROM `%s`.`EmailUser` e | ||
LEFT JOIN UserRole r ON e.emali=r.email WHERE e.email IN %%s""" % db_name | ||
try: | ||
with connection.cursor() as cursor: | ||
cursor.execute(sql, (email_list,)) | ||
res = cursor.fetchall() | ||
except Exception as e: | ||
logger.error('Failed to query email_user object list from ccnet_db, error: %s.' % e) | ||
return list(), api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') | ||
|
||
user_objs = list() | ||
for email, is_staff, is_active, ctime, role in res: | ||
user_objs.append(UserObj(email, ctime, is_staff, is_active, role)) | ||
|
||
return user_objs, None | ||
|
||
|
||
def ldap_bind(server_url, dn, authc_id, password, enable_sasl, sasl_mechanism): | ||
|
@@ -164,7 +190,7 @@ def get_ldap_users(server_url, admin_dn, admin_password, enable_sasl, sasl_mecha | |
break | ||
ctrl.cookie = page_ctrls[0].cookie | ||
|
||
# get ldap user's uid list, uid means login_attr, likes: ['[email protected]', ...] | ||
# get ldap user's uid list, uid means login_attr, likes: ['uid1', 'uid2', 'uid3', 'uid5', ...] | ||
ldap_uid_list = list() | ||
for pair in result_data: | ||
user_dn, attrs = pair | ||
|
@@ -175,32 +201,25 @@ def get_ldap_users(server_url, admin_dn, admin_password, enable_sasl, sasl_mecha | |
uid = attrs[login_attr][0].lower().decode() | ||
ldap_uid_list.append(uid) | ||
|
||
# get uid_email_map, likes {'ldap@email.com': 'seafile@email.com', ...} | ||
ldap_users = SocialAuthUser.objects.filter(provider__in=[LDAP_PROVIDER, MULTI_LDAP_1_PROVIDER], | ||
uid__in=ldap_uid_list) | ||
# get uid_email_map, likes {'uid2': '2@2.com', 'uid3': '[email protected]', 'uid4': '4@4.com', ...} | ||
imported_ldap_users = SocialAuthUser.objects.filter(provider__in=[LDAP_PROVIDER, MULTI_LDAP_1_PROVIDER], | ||
uid__in=ldap_uid_list) | ||
uid_email_map = dict() | ||
for user in ldap_users: | ||
for user in imported_ldap_users: | ||
uid_email_map[user.uid] = user.username | ||
|
||
# get email_ctime_map, likes {'[email protected]': 1692950099, ...} | ||
email_ctime_map = dict() | ||
db_users = ccnet_api.get_emailusers_in_list('DB', json.dumps(list(uid_email_map.values()))) | ||
for user in db_users: | ||
email_ctime_map[user.email] = user.ctime | ||
|
||
users = list() | ||
email_list = list() | ||
for uid in ldap_uid_list: | ||
""" | ||
uid_email_map[uid] -> {'[email protected]': '[email protected]', ...}['[email protected]'] -> '[email protected]' | ||
""" | ||
""" | ||
email_ctime_map[uid_email_map[uid]] -> email_ctime_map['[email protected]'] -> | ||
{'[email protected]': 1692950099, ...}['[email protected]'] -> 1692950099 | ||
""" | ||
if uid in uid_email_map and uid_email_map[uid] in email_ctime_map: | ||
users.append(LdapUser(uid_email_map[uid], email_ctime_map[uid_email_map[uid]])) | ||
if uid in uid_email_map: | ||
email_list.append(uid_email_map[uid]) | ||
else: | ||
users.append(LdapUser(uid, None)) | ||
users.append(UserObj(uid, None, None, None, None)) | ||
|
||
user_objs, error = get_user_objs_from_ccnet(email_list) | ||
if error: | ||
raise Exception('Failed to query email_user object list from ccnet_db.') | ||
users.extend(user_objs) | ||
|
||
return users | ||
|
||
|
@@ -536,7 +555,9 @@ def get_info_of_users_order_by_quota_usage(self, source, direction, | |
if ENABLE_MULTI_LDAP: | ||
multi_ldap_users = SocialAuthUser.objects.filter(provider=MULTI_LDAP_1_PROVIDER) | ||
email_list.extend([user.username for user in multi_ldap_users]) | ||
users = ccnet_api.get_emailusers_in_list('DB', json.dumps(email_list)) | ||
users, error = get_user_objs_from_ccnet(email_list) | ||
if error: | ||
return error | ||
|
||
for user in users: | ||
email = user.email | ||
|
@@ -681,7 +702,9 @@ def get(self, request): | |
if ENABLE_MULTI_LDAP: | ||
multi_ldap_users = SocialAuthUser.objects.filter(provider=MULTI_LDAP_1_PROVIDER) | ||
email_list.extend([user.username for user in multi_ldap_users]) | ||
all_ldap_users = ccnet_api.get_emailusers_in_list('DB', json.dumps(email_list)) | ||
all_ldap_users, error = get_user_objs_from_ccnet(email_list) | ||
if error: | ||
return error | ||
users = all_ldap_users[start: start + per_page] | ||
|
||
data = [] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# -*- coding: utf-8 -*- | ||
import os | ||
import configparser | ||
|
||
|
||
def get_ccnet_db_name(): | ||
ccnet_conf_dir = os.environ.get('SEAFILE_CENTRAL_CONF_DIR') or os.environ.get('CCNET_CONF_DIR') | ||
if not ccnet_conf_dir: | ||
error_msg = 'Environment variable ccnet_conf_dir is not define.' | ||
return None, error_msg | ||
|
||
ccnet_conf_path = os.path.join(ccnet_conf_dir, 'ccnet.conf') | ||
config = configparser.ConfigParser() | ||
config.read(ccnet_conf_path) | ||
|
||
if config.has_section('Database'): | ||
db_name = config.get('Database', 'DB', fallback='ccnet') | ||
else: | ||
db_name = 'ccnet' | ||
|
||
if config.get('Database', 'ENGINE') != 'mysql': | ||
error_msg = 'Failed to init ccnet db, only mysql db supported.' | ||
return None, error_msg | ||
return db_name, None |