core: fix token identifier not being set to unique

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-06-03 11:45:48 +02:00
parent cde056825e
commit 48e68d6852
3 changed files with 47 additions and 7 deletions

View File

@ -0,0 +1,35 @@
# Generated by Django 3.2.3 on 2021-06-03 09:33
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.models import Count
def fix_duplicates(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
Token = apps.get_model("authentik_core", "token")
identifiers = (
Token.objects.using(db_alias)
.values("identifier")
.annotate(identifier_count=Count("identifier"))
.filter(identifier_count__gt=1)
)
for ident in identifiers:
Token.objects.using(db_alias).filter(identifier=ident["identifier"]).delete()
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0023_alter_application_meta_launch_url"),
]
operations = [
migrations.RunPython(fix_duplicates),
migrations.AlterField(
model_name="token",
name="identifier",
field=models.SlugField(max_length=255, unique=True),
),
]

View File

@ -404,7 +404,7 @@ class Token(ManagedModel, ExpiringModel):
"""Token used to authenticate the User for API Access or confirm another Stage like Email.""" """Token used to authenticate the User for API Access or confirm another Stage like Email."""
token_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) token_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
identifier = models.SlugField(max_length=255) identifier = models.SlugField(max_length=255, unique=True)
key = models.TextField(default=default_token_key) key = models.TextField(default=default_token_key)
intent = models.TextField( intent = models.TextField(
choices=TokenIntents.choices, default=TokenIntents.INTENT_VERIFICATION choices=TokenIntents.choices, default=TokenIntents.INTENT_VERIFICATION

View File

@ -376,20 +376,25 @@ class Outpost(models.Model):
@property @property
def token(self) -> Token: def token(self) -> Token:
"""Get/create token for auto-generated user""" """Get/create token for auto-generated user"""
token = Token.filter_not_expired( managed = f"goauthentik.io/outpost/{self.token_identifier}"
user=self.user, tokens = Token.filter_not_expired(
identifier=self.token_identifier,
intent=TokenIntents.INTENT_API, intent=TokenIntents.INTENT_API,
managed=f"goauthentik.io/outpost/{self.token_identifier}", managed=managed,
) )
if token.exists(): if tokens.exists():
return token.first() token = tokens.first()
if not token.managed:
token.managed = managed
token.save()
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=f"goauthentik.io/outpost/{self.token_identifier}", managed=managed,
) )
def get_required_objects(self) -> Iterable[Union[models.Model, str]]: def get_required_objects(self) -> Iterable[Union[models.Model, str]]: