Compare commits
	
		
			3 Commits
		
	
	
		
			version/20
			...
			expiring-m
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 929e42d3f2 | |||
| 863958b4d6 | |||
| 2249b9307e | 
@ -802,12 +802,25 @@ class ExpiringModel(models.Model):
 | 
			
		||||
        return self.delete(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def filter_not_expired(cls, **kwargs) -> QuerySet["Token"]:
 | 
			
		||||
    def _not_expired_filter(cls):
 | 
			
		||||
        return Q(expires__gt=now(), expiring=True) | Q(expiring=False)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def filter_not_expired(cls, delete_expired=False, **kwargs) -> QuerySet["ExpiringModel"]:
 | 
			
		||||
        """Filer for tokens which are not expired yet or are not expiring,
 | 
			
		||||
        and match filters in `kwargs`"""
 | 
			
		||||
        for obj in cls.objects.filter(**kwargs).filter(Q(expires__lt=now(), expiring=True)):
 | 
			
		||||
            obj.delete()
 | 
			
		||||
        return cls.objects.filter(**kwargs)
 | 
			
		||||
        if delete_expired:
 | 
			
		||||
            cls.delete_expired(**kwargs)
 | 
			
		||||
        return cls.objects.filter(cls._not_expired_filter()).filter(**kwargs)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def delete_expired(cls, **kwargs) -> int:
 | 
			
		||||
        objects = cls.objects.all().exclude(cls._not_expired_filter()).filter(**kwargs)
 | 
			
		||||
        amount = 0
 | 
			
		||||
        for obj in objects:
 | 
			
		||||
            obj.expire_action()
 | 
			
		||||
            amount += 1
 | 
			
		||||
        return amount
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_expired(self) -> bool:
 | 
			
		||||
 | 
			
		||||
@ -30,12 +30,7 @@ def clean_expired_models(self: SystemTask):
 | 
			
		||||
    messages = []
 | 
			
		||||
    for cls in ExpiringModel.__subclasses__():
 | 
			
		||||
        cls: ExpiringModel
 | 
			
		||||
        objects = (
 | 
			
		||||
            cls.objects.all().exclude(expiring=False).exclude(expiring=True, expires__gt=now())
 | 
			
		||||
        )
 | 
			
		||||
        amount = objects.count()
 | 
			
		||||
        for obj in objects:
 | 
			
		||||
            obj.expire_action()
 | 
			
		||||
        amount = cls.delete_expired()
 | 
			
		||||
        LOGGER.debug("Expired models", model=cls, amount=amount)
 | 
			
		||||
        messages.append(f"Expired {amount} {cls._meta.verbose_name_plural}")
 | 
			
		||||
    # Special case
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ from uuid import uuid4
 | 
			
		||||
from dacite.core import from_dict
 | 
			
		||||
from django.contrib.auth.models import Permission
 | 
			
		||||
from django.core.cache import cache
 | 
			
		||||
from django.db import IntegrityError, models, transaction
 | 
			
		||||
from django.db import models, transaction
 | 
			
		||||
from django.db.models.base import Model
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from guardian.models import UserObjectPermission
 | 
			
		||||
@ -380,13 +380,14 @@ class Outpost(SerializerModel, ManagedModel):
 | 
			
		||||
        """Get/create token for auto-generated user"""
 | 
			
		||||
        managed = f"goauthentik.io/outpost/{self.token_identifier}"
 | 
			
		||||
        tokens = Token.filter_not_expired(
 | 
			
		||||
            delete_expired=True,
 | 
			
		||||
            identifier=self.token_identifier,
 | 
			
		||||
            intent=TokenIntents.INTENT_API,
 | 
			
		||||
            managed=managed,
 | 
			
		||||
        )
 | 
			
		||||
        if tokens.exists():
 | 
			
		||||
            return tokens.first()
 | 
			
		||||
        try:
 | 
			
		||||
        token: Token | None = tokens.first()
 | 
			
		||||
        if token:
 | 
			
		||||
            return token
 | 
			
		||||
        return Token.objects.create(
 | 
			
		||||
            user=self.user,
 | 
			
		||||
            identifier=self.token_identifier,
 | 
			
		||||
@ -395,11 +396,6 @@ class Outpost(SerializerModel, ManagedModel):
 | 
			
		||||
            expiring=False,
 | 
			
		||||
            managed=managed,
 | 
			
		||||
        )
 | 
			
		||||
        except IntegrityError:
 | 
			
		||||
            # Integrity error happens mostly when managed is reused
 | 
			
		||||
            Token.objects.filter(managed=managed).delete()
 | 
			
		||||
            Token.objects.filter(identifier=self.token_identifier).delete()
 | 
			
		||||
            return self.token
 | 
			
		||||
 | 
			
		||||
    def get_required_objects(self) -> Iterable[models.Model | str]:
 | 
			
		||||
        """Get an iterator of all objects the user needs read access to"""
 | 
			
		||||
 | 
			
		||||
@ -96,8 +96,9 @@ class ConsentStageView(ChallengeStageView):
 | 
			
		||||
        if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
 | 
			
		||||
            user = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
 | 
			
		||||
 | 
			
		||||
        # Remove expired consents to prevent database unique constraints errors
 | 
			
		||||
        consent: UserConsent | None = UserConsent.filter_not_expired(
 | 
			
		||||
            user=user, application=application
 | 
			
		||||
            delete_expired=True, user=user, application=application
 | 
			
		||||
        ).first()
 | 
			
		||||
        self.executor.plan.context[PLAN_CONTEXT_CONSENT] = consent
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user