Compare commits
3 Commits
main
...
expiring-m
Author | SHA1 | Date | |
---|---|---|---|
929e42d3f2 | |||
863958b4d6 | |||
2249b9307e |
@ -802,12 +802,25 @@ class ExpiringModel(models.Model):
|
|||||||
return self.delete(*args, **kwargs)
|
return self.delete(*args, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@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,
|
"""Filer for tokens which are not expired yet or are not expiring,
|
||||||
and match filters in `kwargs`"""
|
and match filters in `kwargs`"""
|
||||||
for obj in cls.objects.filter(**kwargs).filter(Q(expires__lt=now(), expiring=True)):
|
if delete_expired:
|
||||||
obj.delete()
|
cls.delete_expired(**kwargs)
|
||||||
return cls.objects.filter(**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
|
@property
|
||||||
def is_expired(self) -> bool:
|
def is_expired(self) -> bool:
|
||||||
|
@ -30,12 +30,7 @@ def clean_expired_models(self: SystemTask):
|
|||||||
messages = []
|
messages = []
|
||||||
for cls in ExpiringModel.__subclasses__():
|
for cls in ExpiringModel.__subclasses__():
|
||||||
cls: ExpiringModel
|
cls: ExpiringModel
|
||||||
objects = (
|
amount = cls.delete_expired()
|
||||||
cls.objects.all().exclude(expiring=False).exclude(expiring=True, expires__gt=now())
|
|
||||||
)
|
|
||||||
amount = objects.count()
|
|
||||||
for obj in objects:
|
|
||||||
obj.expire_action()
|
|
||||||
LOGGER.debug("Expired models", model=cls, amount=amount)
|
LOGGER.debug("Expired models", model=cls, amount=amount)
|
||||||
messages.append(f"Expired {amount} {cls._meta.verbose_name_plural}")
|
messages.append(f"Expired {amount} {cls._meta.verbose_name_plural}")
|
||||||
# Special case
|
# Special case
|
||||||
|
@ -9,7 +9,7 @@ from uuid import uuid4
|
|||||||
from dacite.core import from_dict
|
from dacite.core import from_dict
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.core.cache import cache
|
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.db.models.base import Model
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from guardian.models import UserObjectPermission
|
from guardian.models import UserObjectPermission
|
||||||
@ -380,26 +380,22 @@ class Outpost(SerializerModel, ManagedModel):
|
|||||||
"""Get/create token for auto-generated user"""
|
"""Get/create token for auto-generated user"""
|
||||||
managed = f"goauthentik.io/outpost/{self.token_identifier}"
|
managed = f"goauthentik.io/outpost/{self.token_identifier}"
|
||||||
tokens = Token.filter_not_expired(
|
tokens = Token.filter_not_expired(
|
||||||
|
delete_expired=True,
|
||||||
identifier=self.token_identifier,
|
identifier=self.token_identifier,
|
||||||
intent=TokenIntents.INTENT_API,
|
intent=TokenIntents.INTENT_API,
|
||||||
managed=managed,
|
managed=managed,
|
||||||
)
|
)
|
||||||
if tokens.exists():
|
token: Token | None = tokens.first()
|
||||||
return tokens.first()
|
if token:
|
||||||
try:
|
return token
|
||||||
return Token.objects.create(
|
return Token.objects.create(
|
||||||
user=self.user,
|
user=self.user,
|
||||||
identifier=self.token_identifier,
|
identifier=self.token_identifier,
|
||||||
intent=TokenIntents.INTENT_API,
|
intent=TokenIntents.INTENT_API,
|
||||||
description=f"Autogenerated by authentik for Outpost {self.name}",
|
description=f"Autogenerated by authentik for Outpost {self.name}",
|
||||||
expiring=False,
|
expiring=False,
|
||||||
managed=managed,
|
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]:
|
def get_required_objects(self) -> Iterable[models.Model | str]:
|
||||||
"""Get an iterator of all objects the user needs read access to"""
|
"""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:
|
if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
|
||||||
user = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
|
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(
|
consent: UserConsent | None = UserConsent.filter_not_expired(
|
||||||
user=user, application=application
|
delete_expired=True, user=user, application=application
|
||||||
).first()
|
).first()
|
||||||
self.executor.plan.context[PLAN_CONTEXT_CONSENT] = consent
|
self.executor.plan.context[PLAN_CONTEXT_CONSENT] = consent
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user