diff --git a/allianceauth/corputils/migrations/0002_migrate_permissions.py b/allianceauth/corputils/migrations/0002_migrate_permissions.py index cd75c9dc..0d0db9aa 100644 --- a/allianceauth/corputils/migrations/0002_migrate_permissions.py +++ b/allianceauth/corputils/migrations/0002_migrate_permissions.py @@ -70,7 +70,7 @@ def forward(apps, schema_editor): perm.delete() -def reverse(apps, schema_editor): +def reverse(apps, schema_editor): # noqa: C901 perm_dict = user_permissions_dict(apps) corp_users = users_with_permission(apps, perm_dict['corpstats']['view_corp_corpstats']) diff --git a/allianceauth/corputils/views.py b/allianceauth/corputils/views.py index d0e62690..67d846ea 100644 --- a/allianceauth/corputils/views.py +++ b/allianceauth/corputils/views.py @@ -62,7 +62,7 @@ def corpstats_add(request, token): @login_required @user_passes_test(access_corpstats_test) -def corpstats_view(request, corp_id=None): +def corpstats_view(request, corp_id=None): # noqa: C901 corpstats = None # get requested model diff --git a/allianceauth/eveonline/admin.py b/allianceauth/eveonline/admin.py index 69d428df..b75b759a 100644 --- a/allianceauth/eveonline/admin.py +++ b/allianceauth/eveonline/admin.py @@ -49,8 +49,8 @@ class EveFactionForm(EveEntityForm): def clean_id(self): try: assert self.Meta.model.provider.get_faction(self.cleaned_data['id']) - except (AssertionError, ObjectNotFound): - raise EveEntityNotFoundError('faction', self.cleaned_data['id']) + except (AssertionError, ObjectNotFound) as e: + raise EveEntityNotFoundError('faction', self.cleaned_data['id']) from e if self.Meta.model.objects.filter(faction_id=self.cleaned_data['id']).exists(): raise EveEntityExistsError('faction', self.cleaned_data['id']) return self.cleaned_data['id'] @@ -70,8 +70,8 @@ class EveCharacterForm(EveEntityForm): def clean_id(self): try: assert self.Meta.model.provider.get_character(self.cleaned_data['id']) - except (AssertionError, ObjectNotFound): - raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) + except (AssertionError, ObjectNotFound) as e: + raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) from e if self.Meta.model.objects.filter(character_id=self.cleaned_data['id']).exists(): raise EveEntityExistsError(self.entity_type_name, self.cleaned_data['id']) return self.cleaned_data['id'] @@ -90,8 +90,8 @@ class EveCorporationForm(EveEntityForm): def clean_id(self): try: assert self.Meta.model.provider.get_corporation(self.cleaned_data['id']) - except (AssertionError, ObjectNotFound): - raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) + except (AssertionError, ObjectNotFound) as e: + raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) from e if self.Meta.model.objects.filter(corporation_id=self.cleaned_data['id']).exists(): raise EveEntityExistsError(self.entity_type_name, self.cleaned_data['id']) return self.cleaned_data['id'] @@ -110,8 +110,8 @@ class EveAllianceForm(EveEntityForm): def clean_id(self): try: assert self.Meta.model.provider.get_alliance(self.cleaned_data['id']) - except (AssertionError, ObjectNotFound): - raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) + except (AssertionError, ObjectNotFound) as e: + raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) from e if self.Meta.model.objects.filter(alliance_id=self.cleaned_data['id']).exists(): raise EveEntityExistsError(self.entity_type_name, self.cleaned_data['id']) return self.cleaned_data['id'] diff --git a/allianceauth/eveonline/providers.py b/allianceauth/eveonline/providers.py index 9ba2db92..69203aaa 100644 --- a/allianceauth/eveonline/providers.py +++ b/allianceauth/eveonline/providers.py @@ -223,8 +223,8 @@ class EveSwaggerProvider(EveProvider): faction_id=data['faction_id'] if 'faction_id' in data else None, ) return model - except HTTPNotFound: - raise ObjectNotFound(alliance_id, 'alliance') + except HTTPNotFound as e: + raise ObjectNotFound(alliance_id, 'alliance') from e def get_corp(self, corp_id: int) -> Corporation: """Fetch corporation from ESI.""" @@ -240,8 +240,8 @@ class EveSwaggerProvider(EveProvider): faction_id=data['faction_id'] if 'faction_id' in data else None, ) return model - except HTTPNotFound: - raise ObjectNotFound(corp_id, 'corporation') + except HTTPNotFound as e: + raise ObjectNotFound(corp_id, 'corporation') from e def get_character(self, character_id: int) -> Character: """Fetch character from ESI.""" @@ -256,8 +256,8 @@ class EveSwaggerProvider(EveProvider): faction_id=affiliation['faction_id'] if 'faction_id' in affiliation else None, ) return model - except (HTTPNotFound, HTTPUnprocessableEntity, ObjectNotFound): - raise ObjectNotFound(character_id, 'character') + except (HTTPNotFound, HTTPUnprocessableEntity, ObjectNotFound) as e: + raise ObjectNotFound(character_id, 'character') from e def _fetch_character_name(self, character_id: int) -> str: """Fetch character name from ESI.""" @@ -288,16 +288,16 @@ class EveSwaggerProvider(EveProvider): return Entity(id=f['faction_id'], name=f['name']) else: raise KeyError() - except (HTTPNotFound, HTTPUnprocessableEntity, KeyError): - raise ObjectNotFound(faction_id, 'faction') + except (HTTPNotFound, HTTPUnprocessableEntity, KeyError) as e: + raise ObjectNotFound(faction_id, 'faction') from e def get_itemtype(self, type_id: int) -> ItemType: """Fetch inventory item from ESI.""" try: data = self.client.Universe.get_universe_types_type_id(type_id=type_id).result() return ItemType(id=type_id, name=data['name']) - except (HTTPNotFound, HTTPUnprocessableEntity): - raise ObjectNotFound(type_id, 'type') + except (HTTPNotFound, HTTPUnprocessableEntity) as e: + raise ObjectNotFound(type_id, 'type') from e provider = EveSwaggerProvider() diff --git a/allianceauth/eveonline/tests/esi_client_stub.py b/allianceauth/eveonline/tests/esi_client_stub.py index 9382355c..6b7c3ee1 100644 --- a/allianceauth/eveonline/tests/esi_client_stub.py +++ b/allianceauth/eveonline/tests/esi_client_stub.py @@ -57,11 +57,11 @@ class EsiClientStub: } try: return BravadoOperationStub(data[int(alliance_id)]) - except KeyError: + except KeyError as e: response = BravadoResponseStub( 404, f"Alliance with ID {alliance_id} not found" ) - raise HTTPNotFound(response) + raise HTTPNotFound(response) from e @staticmethod def get_alliances_alliance_id_corporations(alliance_id): @@ -87,11 +87,11 @@ class EsiClientStub: } try: return BravadoOperationStub(data[int(character_id)]) - except KeyError: + except KeyError as e: response = BravadoResponseStub( 404, f"Character with ID {character_id} not found" ) - raise HTTPNotFound(response) + raise HTTPNotFound(response) from e @staticmethod def post_characters_affiliation(characters: list): @@ -147,11 +147,11 @@ class EsiClientStub: } try: return BravadoOperationStub(data[int(corporation_id)]) - except KeyError: + except KeyError as e: response = BravadoResponseStub( 404, f"Corporation with ID {corporation_id} not found" ) - raise HTTPNotFound(response) + raise HTTPNotFound(response) from e class Universe: @staticmethod diff --git a/allianceauth/fleetactivitytracking/views.py b/allianceauth/fleetactivitytracking/views.py index d7c3ee07..5778ce9a 100644 --- a/allianceauth/fleetactivitytracking/views.py +++ b/allianceauth/fleetactivitytracking/views.py @@ -143,7 +143,12 @@ def fatlink_statistics_corp_view(request, corpid, year=None, month=None): @login_required @permission_required('auth.fleetactivitytracking_statistics') -def fatlink_statistics_view(request, year=datetime.date.today().year, month=datetime.date.today().month): +def fatlink_statistics_view(request, year=None, month=None): + if year is None: + year = datetime.date.today().year + if month is None: + month = datetime.date.today().month + year = int(year) month = int(month) start_of_month = datetime.datetime(year, month, 1) @@ -176,9 +181,12 @@ def fatlink_statistics_view(request, year=datetime.date.today().year, month=date @login_required -def fatlink_personal_statistics_view(request, year=datetime.date.today().year): +def fatlink_personal_statistics_view(request, year=None): + if year is None: + year = datetime.date.today().year + year = int(year) - logger.debug("Personal statistics view for year %i called by %s" % (year, request.user)) + logger.debug(f"Personal statistics view for year {year} called by {request.user}") user = request.user logger.debug(f"fatlink_personal_statistics_view called by user {request.user}") diff --git a/allianceauth/groupmanagement/views.py b/allianceauth/groupmanagement/views.py index 1c736573..feab4c91 100644 --- a/allianceauth/groupmanagement/views.py +++ b/allianceauth/groupmanagement/views.py @@ -87,8 +87,8 @@ def group_membership_audit(request, group_id): logger.warning(f"User {request.user} attempted to view the membership of group {group_id} but permission was denied") raise PermissionDenied - except ObjectDoesNotExist: - raise Http404("Group does not exist") + except ObjectDoesNotExist as e: + raise Http404("Group does not exist") from e render_items = {'group': group} entries = RequestLog.objects.filter(group=group).order_by('-date') render_items['entries'] = entries @@ -117,8 +117,8 @@ def group_membership_list(request, group_id): ) raise PermissionDenied - except ObjectDoesNotExist: - raise Http404("Group does not exist") + except ObjectDoesNotExist as e: + raise Http404("Group does not exist") from e group_leaders = group.authgroup.group_leaders.all() members = [] diff --git a/allianceauth/hrapplications/views.py b/allianceauth/hrapplications/views.py index 2102b663..395aac17 100644 --- a/allianceauth/hrapplications/views.py +++ b/allianceauth/hrapplications/views.py @@ -111,8 +111,8 @@ def hr_application_view(request, app_id): logger.debug(f"hr_application_view called by user {request.user} for app id {app_id}") try: app = Application.objects.prefetch_related('responses', 'comments', 'comments__user').get(pk=app_id) - except Application.DoesNotExist: - raise Http404 + except Application.DoesNotExist as e: + raise Http404 from e if request.method == 'POST': if request.user.has_perm('hrapplications.add_applicationcomment'): form = HRApplicationCommentForm(request.POST) diff --git a/allianceauth/menu/models.py b/allianceauth/menu/models.py index 40c91aab..0e097073 100644 --- a/allianceauth/menu/models.py +++ b/allianceauth/menu/models.py @@ -47,7 +47,7 @@ class MenuItem(models.Model): ) # app related properties - hook_hash = models.CharField( + hook_hash = models.CharField( # noqa: DJ001 max_length=64, default=None, null=True, diff --git a/allianceauth/menu/templatetags/menu_menu_items.py b/allianceauth/menu/templatetags/menu_menu_items.py index 6f93b9fb..d09e2012 100644 --- a/allianceauth/menu/templatetags/menu_menu_items.py +++ b/allianceauth/menu/templatetags/menu_menu_items.py @@ -77,7 +77,7 @@ class RenderedMenuItem: self.html_id = hook_obj.html_id -def render_menu(request: HttpRequest) -> list[RenderedMenuItem]: +def render_menu(request: HttpRequest) -> list[RenderedMenuItem]: # noqa: C901 """Return the rendered side menu for including in a template. This function is creating BS5 style menus. diff --git a/allianceauth/permissions_tool/views.py b/allianceauth/permissions_tool/views.py index de4cc281..62ca95ff 100644 --- a/allianceauth/permissions_tool/views.py +++ b/allianceauth/permissions_tool/views.py @@ -48,8 +48,8 @@ def permissions_audit(request, app_label, model, codename): .prefetch_related('group_set', 'user_set', 'state_set', 'state_set__userprofile_set', 'group_set__user_set', 'state_set__userprofile_set__user')\ .get(content_type__app_label=app_label, content_type__model=model, codename=codename) - except Permission.DoesNotExist: - raise Http404 + except Permission.DoesNotExist as e: + raise Http404 from e context = {'permission': { 'permission': perm, diff --git a/allianceauth/services/abstract.py b/allianceauth/services/abstract.py index 034d1dfc..4230af38 100644 --- a/allianceauth/services/abstract.py +++ b/allianceauth/services/abstract.py @@ -33,7 +33,6 @@ class AbstractServiceModel(models.Model): related_name='%(app_label)s' ) - class Meta: abstract = True @@ -85,8 +84,8 @@ class ServicesCRUDMixin(SingleObjectMixin): try: return queryset.get(user__pk=self.request.user.pk) - except ObjectDoesNotExist: - raise Http404 + except ObjectDoesNotExist as e: + raise Http404 from e class BaseDeactivateServiceAccountView(ServicesCRUDMixin, BaseServiceView, DeleteView): diff --git a/allianceauth/services/modules/discord/discord_client/tests/piloting_concurrency.py b/allianceauth/services/modules/discord/discord_client/tests/piloting_concurrency.py index 8d9b73da..20844347 100644 --- a/allianceauth/services/modules/discord/discord_client/tests/piloting_concurrency.py +++ b/allianceauth/services/modules/discord/discord_client/tests/piloting_concurrency.py @@ -44,26 +44,24 @@ MAX_JITTER_PER_RUN_SECS = 1.0 def worker(num: int): """worker function""" - worker_info = 'worker %d' % num - logger.info('%s: started', worker_info) + worker_info = f'worker {num}' + logger.info(f'{worker_info}: started') client = DiscordClient(DISCORD_BOT_TOKEN) try: runs = 0 while runs < NUMBER_OF_RUNS: - run_info = '%s: run %d' % (worker_info, runs + 1) + run_info = f'{worker_info}: run {runs + 1}' my_jitter_secs = random() * MAX_JITTER_PER_RUN_SECS - logger.info('%s - waiting %s secs', run_info, f'{my_jitter_secs:.3f}') + logger.info(f'{run_info} - waiting {my_jitter_secs:.3f} secs') sleep(my_jitter_secs) - logger.info('%s - started', run_info) + logger.info(f'{run_info} - started') try: client.modify_guild_member( DISCORD_GUILD_ID, DISCORD_USER_ID, nick=NICK ) runs += 1 except DiscordApiBackoff as bo: - message = '%s - waiting out API backoff for %d ms' % ( - run_info, bo.retry_after - ) + message = f'{run_info} - waiting out API backoff for {bo.retry_after} ms' logger.info(message) print() print(message) diff --git a/allianceauth/services/modules/discord/tasks.py b/allianceauth/services/modules/discord/tasks.py index 15e6319a..9881aed8 100644 --- a/allianceauth/services/modules/discord/tasks.py +++ b/allianceauth/services/modules/discord/tasks.py @@ -89,12 +89,12 @@ def _task_perform_user_action(self, user_pk: int, method: str, **kwargs) -> None bo, bo.retry_after_seconds ) - raise self.retry(countdown=bo.retry_after_seconds) + raise self.retry(exc=bo, countdown=bo.retry_after_seconds) from bo - except AttributeError: - raise ValueError(f'{method} not a valid method for DiscordUser') + except AttributeError as e: + raise ValueError(f'{method} not a valid method for DiscordUser') from e - except (HTTPError, ConnectionError): + except (HTTPError, ConnectionError) as e: logger.warning( '%s failed for user %s, retrying in %d secs', method, @@ -103,7 +103,7 @@ def _task_perform_user_action(self, user_pk: int, method: str, **kwargs) -> None exc_info=True ) if self.request.retries < DISCORD_TASKS_MAX_RETRIES: - raise self.retry(countdown=DISCORD_TASKS_RETRY_PAUSE) + raise self.retry(exc=e, countdown=DISCORD_TASKS_RETRY_PAUSE) from e else: logger.error( '%s failed for user %s after max retries', @@ -192,8 +192,8 @@ def _task_perform_users_action(self, method: str, **kwargs) -> Any: try: result = getattr(DiscordUser.objects, method)(**kwargs) - except AttributeError: - raise ValueError(f'{method} not a valid method for DiscordUser.objects') + except AttributeError as e: + raise ValueError(f'{method} not a valid method for DiscordUser.objects') from e except DiscordApiBackoff as bo: logger.info( @@ -202,9 +202,9 @@ def _task_perform_users_action(self, method: str, **kwargs) -> Any: bo, bo.retry_after_seconds ) - raise self.retry(countdown=bo.retry_after_seconds) + raise self.retry(exc=bo, countdown=bo.retry_after_seconds) from bo - except (HTTPError, ConnectionError): + except (HTTPError, ConnectionError)as e: logger.warning( '%s failed, retrying in %d secs', method, @@ -212,7 +212,7 @@ def _task_perform_users_action(self, method: str, **kwargs) -> Any: exc_info=True ) if self.request.retries < DISCORD_TASKS_MAX_RETRIES: - raise self.retry(countdown=DISCORD_TASKS_RETRY_PAUSE) + raise self.retry(exc=e, countdown=DISCORD_TASKS_RETRY_PAUSE) from e else: logger.error('%s failed after max retries', method, exc_info=True) diff --git a/allianceauth/services/modules/discourse/tasks.py b/allianceauth/services/modules/discourse/tasks.py index 48487e1f..08b281e1 100644 --- a/allianceauth/services/modules/discourse/tasks.py +++ b/allianceauth/services/modules/discourse/tasks.py @@ -52,7 +52,7 @@ class DiscourseTasks: except Exception as e: logger.exception(e) logger.warning(f"Discourse group sync failed for {user}, retrying in 10 mins") - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e logger.debug(f"Updated user {user} discourse groups.") @staticmethod diff --git a/allianceauth/services/modules/mumble/tasks.py b/allianceauth/services/modules/mumble/tasks.py index 967abd9f..f88ec297 100644 --- a/allianceauth/services/modules/mumble/tasks.py +++ b/allianceauth/services/modules/mumble/tasks.py @@ -41,9 +41,9 @@ class MumbleTasks: return True except MumbleUser.DoesNotExist: logger.info(f"Mumble group sync failed for {user}, user does not have a mumble account") - except Exception: + except Exception as e: logger.exception(f"Mumble group sync failed for {user}, retrying in 10 mins") - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e else: logger.debug(f"User {user} does not have a mumble account, skipping") return False @@ -61,9 +61,9 @@ class MumbleTasks: return True except MumbleUser.DoesNotExist: logger.info(f"Mumble display name sync failed for {user}, user does not have a mumble account") - except Exception: + except Exception as e: logger.exception(f"Mumble display name sync failed for {user}, retrying in 10 mins") - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e else: logger.debug(f"User {user} does not have a mumble account, skipping") return False diff --git a/allianceauth/services/modules/openfire/tasks.py b/allianceauth/services/modules/openfire/tasks.py index 6c246d37..60baa3c2 100644 --- a/allianceauth/services/modules/openfire/tasks.py +++ b/allianceauth/services/modules/openfire/tasks.py @@ -54,9 +54,9 @@ class OpenfireTasks: logger.debug(f"Updating user {user} jabber groups to {groups}") try: OpenfireManager.update_user_groups(user.openfire.username, groups) - except Exception: + except Exception as e: logger.exception(f"Jabber group sync failed for {user}, retrying in 10 mins") - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e logger.debug(f"Updated user {user} jabber groups.") else: logger.debug("User does not have an openfire account") diff --git a/allianceauth/services/modules/phpbb3/models.py b/allianceauth/services/modules/phpbb3/models.py index a283d4b4..0d9d1d1c 100644 --- a/allianceauth/services/modules/phpbb3/models.py +++ b/allianceauth/services/modules/phpbb3/models.py @@ -8,10 +8,10 @@ class Phpbb3User(models.Model): related_name='phpbb3') username = models.CharField(max_length=254) - def __str__(self): - return self.username - class Meta: permissions = ( ("access_phpbb3", "Can access the phpBB3 service"), ) + + def __str__(self) -> str: + return self.username diff --git a/allianceauth/services/modules/phpbb3/tasks.py b/allianceauth/services/modules/phpbb3/tasks.py index 88d9d3bb..5d64812f 100644 --- a/allianceauth/services/modules/phpbb3/tasks.py +++ b/allianceauth/services/modules/phpbb3/tasks.py @@ -49,9 +49,9 @@ class Phpbb3Tasks: logger.debug(f"Updating user {user} phpbb3 groups to {groups}") try: Phpbb3Manager.update_groups(user.phpbb3.username, groups) - except Exception: + except Exception as e: logger.exception(f"Phpbb group sync failed for {user}, retrying in 10 mins") - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e logger.debug(f"Updated user {user} phpbb3 groups.") else: logger.debug("User does not have a Phpbb3 account") diff --git a/allianceauth/services/modules/smf/tasks.py b/allianceauth/services/modules/smf/tasks.py index 9cac03a3..e57b1d1e 100644 --- a/allianceauth/services/modules/smf/tasks.py +++ b/allianceauth/services/modules/smf/tasks.py @@ -53,9 +53,9 @@ class SmfTasks: logger.debug(f"Updating user {user} smf groups to {groups}") try: SmfManager.update_groups(user.smf.username, groups) - except Exception: + except Exception as e: logger.exception(f"smf group sync failed for {user}, retrying in 10 mins") - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e logger.debug(f"Updated user {user} smf groups.") else: logger.debug("User does not have an smf account") @@ -77,11 +77,11 @@ class SmfTasks: f"SMF displayed name sync failed for {user}, " "user does not have a SMF account" ) - except Exception: + except Exception as e: logger.exception( f"SMF displayed name sync failed for {user}, retrying in 10 mins" ) - raise self.retry(countdown=60 * 10) + raise self.retry(exc=e, countdown=60 * 10) from e else: logger.debug(f"User {user} does not have a SMF account, skipping") diff --git a/allianceauth/services/modules/teamspeak3/tasks.py b/allianceauth/services/modules/teamspeak3/tasks.py index 61b0792f..046f9eed 100644 --- a/allianceauth/services/modules/teamspeak3/tasks.py +++ b/allianceauth/services/modules/teamspeak3/tasks.py @@ -81,7 +81,7 @@ class Teamspeak3Tasks: logger.debug(f"Updated user {user} teamspeak3 groups.") except TeamspeakError as e: logger.error(f"Error occured while syncing TS groups for {user}: {str(e)}") - raise self.retry(countdown=60*10) + raise self.retry(exc=e, countdown=60 * 10) from e else: logger.debug("User does not have a teamspeak3 account") diff --git a/allianceauth/services/modules/teamspeak3/util/ts3.py b/allianceauth/services/modules/teamspeak3/util/ts3.py index 358a1b58..bad23fbd 100644 --- a/allianceauth/services/modules/teamspeak3/util/ts3.py +++ b/allianceauth/services/modules/teamspeak3/util/ts3.py @@ -182,7 +182,7 @@ class TS3Proto: """ if isinstance(value, int): - return "%d" % value + return f"{value}" value = value.replace("\\", r'\\') for i, j in ts3_escape.items(): value = value.replace(i, j) @@ -197,7 +197,7 @@ class TS3Proto: """ if isinstance(value, int): - return "%d" % value + return f"{value}" value = value.replace(r"\\", "\\") for i, j in ts3_escape.items(): value = value.replace(j, i) diff --git a/allianceauth/services/signals.py b/allianceauth/services/signals.py index 167aadd8..2fb97740 100644 --- a/allianceauth/services/signals.py +++ b/allianceauth/services/signals.py @@ -68,8 +68,8 @@ def m2m_changed_group_permissions(sender, instance, action, pk_set, *args, **kwa logger.debug(f"Received m2m_changed from group {instance} permissions with action {action}") if instance.pk and (action == "post_remove" or action == "post_clear"): logger.debug(f"Checking if service permission changed for group {instance}") - # As validating an entire groups service could lead to many thousands of permission checks - # first we check that one of the permissions changed is, in fact, a service permission. + # As validating an entire group's service could lead to many thousands of permission checks, + # first, we check that one of the permissions changed is, in fact, a service permission. perms = Permission.objects.filter(pk__in=pk_set) got_change = False service_perms = [svc.access_perm for svc in ServicesHook.get_services()] @@ -81,18 +81,19 @@ def m2m_changed_group_permissions(sender, instance, action, pk_set, *args, **kwa continue for svc in ServicesHook.get_services(): if svc.access_perm == path_perm: - logger.debug(f"Permissions changed for group {instance} on service {svc}, re-validating services for groups users") + logger.debug(f"Permissions changed for group {instance} on service {svc}, re-validating services for group users") - def validate_all_groups_users_for_service(): - logger.debug(f"Performing validation for service {svc}") + def validate_all_groups_users_for_service(service): + logger.debug(f"Performing validation for service {service}") for user in instance.user_set.all(): - svc.validate_user(user) + service.validate_user(user) - transaction.on_commit(validate_all_groups_users_for_service) + transaction.on_commit(lambda service=svc: validate_all_groups_users_for_service(service)) got_change = True break # Found service, break out of services iteration and go back to permission iteration if not got_change: - logger.debug(f"Permission change for group {instance} was not service permission, ignoring") + logger.debug(f"Permission change for group {instance} was not a service permission, ignoring") + @receiver(m2m_changed, sender=State.permissions.through) @@ -115,12 +116,12 @@ def m2m_changed_state_permissions(sender, instance, action, pk_set, *args, **kwa if svc.access_perm == path_perm: logger.debug(f"Permissions changed for state {instance} on service {svc}, re-validating services for state users") - def validate_all_state_users_for_service(): - logger.debug(f"Performing validation for service {svc}") + def validate_all_state_users_for_service(service): + logger.debug(f"Performing validation for service {service}") for profile in instance.userprofile_set.all(): - svc.validate_user(profile.user) + service.validate_user(profile.user) - transaction.on_commit(validate_all_state_users_for_service) + transaction.on_commit(lambda service=svc: validate_all_state_users_for_service(service)) got_change = True break # Found service, break out of services iteration and go back to permission iteration if not got_change: