Skip to content

Commit 2d2d4bb

Browse files
committed
Fix a bug with badge calculation
1 parent c4178ee commit 2d2d4bb

2 files changed

Lines changed: 87 additions & 1 deletion

File tree

astra_app/core/membership.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,68 @@ def visible_committee_membership_requests(
726726
return visible_requests
727727

728728

729+
def auto_ignore_pending_requests_for_deleted_users() -> int:
730+
"""Auto-ignore pending requests for users that no longer exist in FreeIPA.
731+
732+
Can be called from cache invalidation handlers or routine operations.
733+
Returns count of requests that were auto-ignored.
734+
"""
735+
from core.membership_request_workflow import ignore_membership_request
736+
737+
try:
738+
live_usernames = _normalize_live_usernames(None)
739+
except Exception:
740+
# If FreeIPA is unavailable, don't auto-ignore anything
741+
logger.debug("skipped_auto_ignore_freeipa_unavailable")
742+
return 0
743+
744+
ignored_count = 0
745+
pending_all = list(MembershipRequest.objects.filter(status=MembershipRequest.Status.pending))
746+
747+
for request in pending_all:
748+
# Only auto-ignore user targets (not org targets).
749+
if request.is_organization_target:
750+
continue
751+
752+
normalized_username = str(request.requested_username or "").strip().lower()
753+
if not normalized_username or normalized_username in live_usernames:
754+
continue
755+
756+
# User doesn't exist in FreeIPA; auto-ignore the request.
757+
try:
758+
ignore_membership_request(
759+
membership_request=request,
760+
actor_username="system",
761+
)
762+
ignored_count += 1
763+
logger.info(
764+
"auto_ignored_pending_request_for_deleted_user request_id=%s username=%s",
765+
request.pk,
766+
request.requested_username,
767+
extra={
768+
"event": "astra.membership.auto_ignore",
769+
"component": "membership",
770+
"outcome": "deleted_user",
771+
},
772+
)
773+
except Exception:
774+
logger.exception(
775+
"failed_to_auto_ignore_pending_request_for_deleted_user request_id=%s username=%s",
776+
request.pk,
777+
request.requested_username,
778+
)
779+
780+
return ignored_count
781+
782+
783+
def invalidate_membership_review_badge_cache() -> None:
784+
"""Invalidate the cached membership review badge counts."""
785+
try:
786+
cache.delete(_MEMBERSHIP_REVIEW_BADGE_COUNTS_CACHE_KEY)
787+
except Exception:
788+
pass
789+
790+
729791
def get_membership_review_badge_counts() -> dict[str, int]:
730792
try:
731793
cached_counts = cache.get(_MEMBERSHIP_REVIEW_BADGE_COUNTS_CACHE_KEY)

astra_app/core/models.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from django.core.validators import MaxValueValidator, MinValueValidator
1717
from django.db import IntegrityError, models, transaction
1818
from django.db.models import Q
19-
from django.db.models.signals import post_save
19+
from django.db.models.signals import post_delete, post_save
2020
from django.dispatch import receiver
2121
from django.utils import timezone
2222
from PIL import Image
@@ -1875,3 +1875,27 @@ def _cleanup_credentials_on_election_soft_delete(
18751875
if update_fields is not None and "status" not in update_fields:
18761876
return
18771877
VotingCredential.objects.filter(election=instance).delete()
1878+
1879+
1880+
@receiver(post_save, sender=MembershipRequest)
1881+
def _invalidate_badge_cache_on_membership_request_change(
1882+
sender: type[MembershipRequest],
1883+
instance: MembershipRequest,
1884+
**kwargs: object,
1885+
) -> None:
1886+
"""Invalidate badge count cache when membership requests change."""
1887+
from core.membership import invalidate_membership_review_badge_cache
1888+
1889+
invalidate_membership_review_badge_cache()
1890+
1891+
1892+
@receiver(post_delete, sender=MembershipRequest)
1893+
def _invalidate_badge_cache_on_membership_request_delete(
1894+
sender: type[MembershipRequest],
1895+
instance: MembershipRequest,
1896+
**kwargs: object,
1897+
) -> None:
1898+
"""Invalidate badge count cache when membership requests are deleted."""
1899+
from core.membership import invalidate_membership_review_badge_cache
1900+
1901+
invalidate_membership_review_badge_cache()

0 commit comments

Comments
 (0)