From 1d0ee7b906e8f8a5df1a48efa0b55c97694cb90b Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Thu, 31 Oct 2024 11:17:17 +0100 Subject: [PATCH] Add sso error sync job --- compose/django/supercronic_crontab | 3 + server/vbv_lernwelt/sso/admin.py | 58 ++++++++++++------- .../vbv_lernwelt/sso/management/__init__.py | 0 .../sso/management/commands/__init__.py | 0 .../commands/handle_sso_sync_errors.py | 35 +++++++++++ 5 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 server/vbv_lernwelt/sso/management/__init__.py create mode 100644 server/vbv_lernwelt/sso/management/commands/__init__.py create mode 100644 server/vbv_lernwelt/sso/management/commands/handle_sso_sync_errors.py diff --git a/compose/django/supercronic_crontab b/compose/django/supercronic_crontab index bd4be3ed..13bd5372 100644 --- a/compose/django/supercronic_crontab +++ b/compose/django/supercronic_crontab @@ -4,6 +4,9 @@ # Run every 6 hours 0 */6 * * * /usr/local/bin/python /app/manage.py simple_dummy_job +# Run every hour at minute 11 +0 */11 * * * /usr/local/bin/python /app/manage.py handle_sso_sync_errors + # Run every hour at minute 17 17 * * * * /usr/local/bin/python /app/manage.py edoniq_import_results diff --git a/server/vbv_lernwelt/sso/admin.py b/server/vbv_lernwelt/sso/admin.py index 1db24124..87f4496f 100644 --- a/server/vbv_lernwelt/sso/admin.py +++ b/server/vbv_lernwelt/sso/admin.py @@ -23,15 +23,17 @@ def create_sso_user_from_admin(user: User, request): try: create_and_update_user(user) # noqa user.save() - messages.add_message( - request, messages.SUCCESS, "Der Bentuzer wurde in Keycloak erstellt." - ) + if request: + messages.add_message( + request, messages.SUCCESS, "Der Bentuzer wurde in Keycloak erstellt." + ) except KeycloakPostError as e: - messages.add_message( - request, - messages.WARNING, - f"Der Benutzer {user} konnte nicht in Keycloak erstellt werden: {e}", - ) + if request: + messages.add_message( + request, + messages.WARNING, + f"Der Benutzer {user} konnte nicht in Keycloak erstellt werden: {e}", + ) def sync_sso_roles_from_admin(user: User, request): @@ -53,21 +55,26 @@ def sync_sso_roles_from_admin(user: User, request): try: sync_roles_for_user(user, course_roles) - messages.add_message( - request, messages.SUCCESS, "Die Daten wurden mit Keycloak synchronisiert." - ) + if request: + messages.add_message( + request, + messages.SUCCESS, + "Die Daten wurden mit Keycloak synchronisiert.", + ) except KeycloakDeleteError as e: - messages.add_message( - request, - messages.WARNING, - f"Die bestehenden Rollen für Benutzer ({user}) konnten in Keycloak nicht gelöscht werden: {e}", - ) + if request: + messages.add_message( + request, + messages.WARNING, + f"Die bestehenden Rollen für Benutzer ({user}) konnten in Keycloak nicht gelöscht werden: {e}", + ) except KeycloakPostError as e: - messages.add_message( - request, - messages.WARNING, - f"Die neuen Rollen für Benutzer ({user}) konnten in Keycloak nicht erstellt werden: {e}", - ) + if request: + messages.add_message( + request, + messages.WARNING, + f"Die neuen Rollen für Benutzer ({user}) konnten in Keycloak nicht erstellt werden: {e}", + ) @admin.action(description="KEYCLOAK: Sync SSO Roles") @@ -98,7 +105,14 @@ class SsoUserAdmin(auth_admin.UserAdmin): "sso_id", "intermedia_sso_id", ] - search_fields = ["first_name", "last_name", "email", "username", "sso_id"] + search_fields = [ + "first_name", + "last_name", + "email", + "username", + "sso_id", + "additional_json_data__intermediate_sso_id", + ] actions = [sync_sso_roles, create_sso_user] # Make fields read-only diff --git a/server/vbv_lernwelt/sso/management/__init__.py b/server/vbv_lernwelt/sso/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/sso/management/commands/__init__.py b/server/vbv_lernwelt/sso/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/sso/management/commands/handle_sso_sync_errors.py b/server/vbv_lernwelt/sso/management/commands/handle_sso_sync_errors.py new file mode 100644 index 00000000..61a838ec --- /dev/null +++ b/server/vbv_lernwelt/sso/management/commands/handle_sso_sync_errors.py @@ -0,0 +1,35 @@ +import djclick as click +import structlog + +from vbv_lernwelt.sso.admin import sync_sso_roles_from_admin +from vbv_lernwelt.sso.models import SsoSyncError + +logger = structlog.get_logger(__name__) + + +@click.command() +@click.option( + "--delete-sync-errors/--no-delete-sync-errors", + default=True, + help="`delete-sync-errors` to delete the erros after sync, `no-delete-sync-errors` to keep the SyncErrors objects. Default is `delete-sync-errors`.", +) +def command(delete_sync_errors: bool): + errors = SsoSyncError.objects.all() + processed_users = set() + errors_to_delete = [] + + for error in errors: + user = error.user + if user.id not in processed_users: + sync_sso_roles_from_admin(user, None) + processed_users.add(user.id) + logger.info( + "sso_sync_error", + user=user.id, + ) + if delete_sync_errors: + errors_to_delete.append(error.id) + + # Perform the bulk delete operation + if errors_to_delete: + SsoSyncError.objects.filter(id__in=errors_to_delete).delete()