diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 44fddfc63..d89415eed 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -374,6 +374,10 @@ defaults = { 'RADIUS_SERVER': 'localhost', 'RADIUS_PORT': 1812, 'RADIUS_SECRET': '', + 'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000, + 'AUTH_LDAP_SYNC_IS_PERIODIC': False, + 'AUTH_LDAP_SYNC_INTERVAL': None, + 'AUTH_LDAP_SYNC_CRONTAB': None, 'HTTP_BIND_HOST': '0.0.0.0', 'HTTP_LISTEN_PORT': 8080, 'WS_LISTEN_PORT': 8070, @@ -386,7 +390,6 @@ defaults = { 'PERM_SINGLE_ASSET_TO_UNGROUP_NODE': False, 'WINDOWS_SSH_DEFAULT_SHELL': 'cmd', 'FLOWER_URL': "127.0.0.1:5555", - 'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000, 'DEFAULT_ORG_SHOW_ALL_USERS': True, } diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index b5184de1a..d2eb26ca7 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -425,6 +425,10 @@ OTP_VALID_WINDOW = CONFIG.OTP_VALID_WINDOW # Auth LDAP settings AUTH_LDAP = False AUTH_LDAP_SEARCH_PAGED_SIZE = CONFIG.AUTH_LDAP_SEARCH_PAGED_SIZE +AUTH_LDAP_SYNC_IS_PERIODIC = CONFIG.AUTH_LDAP_SYNC_IS_PERIODIC +AUTH_LDAP_SYNC_INTERVAL = CONFIG.AUTH_LDAP_SYNC_INTERVAL +AUTH_LDAP_SYNC_CRONTAB = CONFIG.AUTH_LDAP_SYNC_CRONTAB + AUTH_LDAP_SERVER_URI = 'ldap://localhost:389' AUTH_LDAP_BIND_DN = 'cn=admin,dc=jumpserver,dc=org' AUTH_LDAP_BIND_PASSWORD = '' diff --git a/apps/settings/utils.py b/apps/settings/utils.py index 7fc7510dd..657aa4600 100644 --- a/apps/settings/utils.py +++ b/apps/settings/utils.py @@ -170,7 +170,7 @@ class LDAPUtil: email = construct_user_email(username, email) return email - def create_or_update_users(self, user_items, force_update=True): + def create_or_update_users(self, user_items): succeed = failed = 0 for user_item in user_items: exist = user_item.pop('existing', False) @@ -180,13 +180,14 @@ class LDAPUtil: else: ok, error = self.update_user(user_item) if not ok: + logger.info("Failed User: {}".format(user_item)) failed += 1 else: succeed += 1 result = {'total': len(user_items), 'succeed': succeed, 'failed': failed} return result - def sync_users(self, username_list): + def sync_users(self, username_list=None): user_items = self.search_filter_user_items(username_list) result = self.create_or_update_users(user_items) return result diff --git a/apps/users/tasks.py b/apps/users/tasks.py index cbdfd4848..e0051e939 100644 --- a/apps/users/tasks.py +++ b/apps/users/tasks.py @@ -2,6 +2,7 @@ # from celery import shared_task +from django.conf import settings from ops.celery.utils import create_or_update_celery_periodic_tasks from ops.celery.decorator import after_app_ready_start @@ -10,6 +11,7 @@ from .models import User from .utils import ( send_password_expiration_reminder_mail, send_user_expiration_reminder_mail ) +from settings.utils import LDAPUtil logger = get_logger(__file__) @@ -66,3 +68,36 @@ def check_user_expired_periodic(): } create_or_update_celery_periodic_tasks(tasks) + +@shared_task +def sync_ldap_user(): + logger.info("Start sync ldap user periodic task") + util = LDAPUtil() + result = util.sync_users() + logger.info("Result: {}".format(result)) + + +@shared_task +@after_app_ready_start +def sync_ldap_user_periodic(): + if not settings.AUTH_LDAP: + return + if not settings.AUTH_LDAP_SYNC_IS_PERIODIC: + return + + interval = settings.AUTH_LDAP_SYNC_INTERVAL + if isinstance(interval, int): + interval = interval * 3600 + else: + interval = None + crontab = settings.AUTH_LDAP_SYNC_CRONTAB + + tasks = { + 'sync_ldap_user_periodic': { + 'task': sync_ldap_user.name, + 'interval': interval, + 'crontab': crontab, + 'enabled': True, + } + } + create_or_update_celery_periodic_tasks(tasks) diff --git a/config_example.yml b/config_example.yml index 2008ff917..911e7b8ee 100644 --- a/config_example.yml +++ b/config_example.yml @@ -72,6 +72,13 @@ REDIS_PORT: 6379 # RADIUS_PORT: 1812 # RADIUS_SECRET: +# LDAP/AD 设置定时同步参数 +# 启用/禁用 +# AUTH_LDAP_SYNC_IS_PERIODIC: True +# 单位: 时 +# AUTH_LDAP_SYNC_INTERVAL: 12 +# Crontab 表达式 +# AUTH_LDAP_SYNC_CRONTAB: * 6 * * * # OTP settings # OTP/MFA 配置