diff --git a/rhodecode/authentication/views.py b/rhodecode/authentication/views.py index 6b4bb01b..033f9fcf 100644 --- a/rhodecode/authentication/views.py +++ b/rhodecode/authentication/views.py @@ -28,6 +28,7 @@ from rhodecode.apps._base import BaseAppView from rhodecode.authentication.base import get_authn_registry from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired +from rhodecode.lib.celerylib import run_task, tasks from rhodecode.model.forms import AuthSettingsForm from rhodecode.model.meta import Session from rhodecode.model.settings import SettingsModel @@ -90,6 +91,9 @@ class AuthnPluginViewBase(BaseAppView): # Store validated data. for name, value in valid_data.items(): self.plugin.create_or_update_setting(name, value) + if name == "sync_active_directory_users": + self._handle_ad_users_sync_schedule(name, value) + Session().commit() SettingsModel().invalidate_settings_cache() @@ -102,6 +106,17 @@ class AuthnPluginViewBase(BaseAppView): return HTTPFound(redirect_to) + def _handle_ad_users_sync_schedule(self, name: str, enabled: bool): + if name != "sync_active_directory_users": + return + + if enabled: + log.debug("Scheduling AD users sync") + run_task(tasks.schedule_sync_ldap_ad_users_producer) + else: + log.debug("Removing schedule for AD users sync") + run_task(tasks.unschedule_sync_ldap_ad_users_producer) + class AuthSettingsView(BaseAppView): def load_default_context(self): diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py index 8da73f67..943e16bf 100644 --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -24,6 +24,7 @@ by celery daemon import os import time +from celery import current_app from pyramid_mailer.mailer import Mailer from pyramid_mailer.message import Message from email.utils import formatdate @@ -35,7 +36,7 @@ from rhodecode.lib import hooks_base from rhodecode.lib.utils import adopt_for_celery from rhodecode.lib.utils2 import safe_int, str2bool, aslist from rhodecode.lib.statsd_client import StatsdClient -from rhodecode.model.db import true, null, Session, IntegrityError, Repository, RepoGroup, User +from rhodecode.model.db import true, null, Session, IntegrityError, Repository, RepoGroup, User, ScheduleEntry from rhodecode.model.permission import PermissionModel @@ -417,6 +418,47 @@ def beat_check(*args, **kwargs): return time.time() +@async_task(ignore_result=True) +def schedule_sync_ldap_ad_users_producer(): + log = get_logger(schedule_sync_ldap_ad_users_producer) + + try: + from rc_ee.lib.celerylib.scheduler import RcScheduler + except ImportError: + log.error("Attempt to schedule EE feature") + return + + scheduler = RcScheduler(app=current_app) + scheduler.sync() + task_name = "rc_ee.lib.celerylib.tasks.sync_ldap_ad_users_producer" + if task_name not in scheduler.schedule: + entries = { + task_name: { + "task": task_name, + "schedule_type": "crontab", + "schedule_value": {"hour": 0, "minute": 4}, + "options": {"expires": 12 * 3600}, + } + } + scheduler.update_from_dict(entries) + + +@async_task(ignore_result=True) +def unschedule_sync_ldap_ad_users_producer(): + log = get_logger(unschedule_sync_ldap_ad_users_producer) + + try: + from rc_ee.lib.celerylib.scheduler import RcScheduler + except ImportError: + log.error("Attempt to unschedule EE feature") + return + + task_name = "rc_ee.lib.celerylib.tasks.sync_ldap_ad_users_producer" + existing_task = ScheduleEntry.query().filter(ScheduleEntry.task_dot_notation == task_name).first() + if existing_task: + Session().delete(existing_task) + + @async_task @adopt_for_celery def repo_size(extras):