outposts: allow outposts to have non-object specific permissions

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-04-26 23:28:26 +02:00
parent d27dfcc1e3
commit 3ce8b836dc
2 changed files with 18 additions and 8 deletions

View file

@ -5,6 +5,7 @@ from typing import Iterable, Optional, Union
from uuid import uuid4 from uuid import uuid4
from dacite import from_dict from dacite import from_dict
from django.contrib.auth.models import Permission
from django.core.cache import cache from django.core.cache import cache
from django.db import models, transaction from django.db import models, transaction
from django.db.models.base import Model from django.db.models.base import Model
@ -64,7 +65,7 @@ class OutpostConfig:
class OutpostModel(Model): class OutpostModel(Model):
"""Base model for providers that need more objects than just themselves""" """Base model for providers that need more objects than just themselves"""
def get_required_objects(self) -> Iterable[models.Model]: def get_required_objects(self) -> Iterable[Union[models.Model, str]]:
"""Return a list of all required objects""" """Return a list of all required objects"""
return [self] return [self]
@ -335,9 +336,18 @@ class Outpost(models.Model):
# the ones the user needs # the ones the user needs
with transaction.atomic(): with transaction.atomic():
UserObjectPermission.objects.filter(user=user).delete() UserObjectPermission.objects.filter(user=user).delete()
for model in self.get_required_objects(): Permission.objects.filter(user=user).delete()
code_name = f"{model._meta.app_label}.view_{model._meta.model_name}" for model_or_perm in self.get_required_objects():
assign_perm(code_name, user, model) if isinstance(model_or_perm, models.Model):
model_or_perm: models.Model
code_name = (
f"{model_or_perm._meta.app_label}."
f"view_{model_or_perm._meta.model_name}"
)
assign_perm(code_name, user, model_or_perm)
else:
assign_perm(model_or_perm, user)
LOGGER.debug("Updated service account's permissions")
return user return user
@property @property
@ -360,9 +370,9 @@ class Outpost(models.Model):
managed=f"goauthentik.io/outpost/{self.token_identifier}", managed=f"goauthentik.io/outpost/{self.token_identifier}",
) )
def get_required_objects(self) -> Iterable[models.Model]: def get_required_objects(self) -> Iterable[Union[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"""
objects = [self] objects: list[Union[models.Model, str]] = [self]
for provider in ( for provider in (
Provider.objects.filter(outpost=self).select_related().select_subclasses() Provider.objects.filter(outpost=self).select_related().select_subclasses()
): ):

View file

@ -1,7 +1,7 @@
"""authentik proxy models""" """authentik proxy models"""
import string import string
from random import SystemRandom from random import SystemRandom
from typing import Iterable, Optional, Type from typing import Iterable, Optional, Type, Union
from urllib.parse import urljoin from urllib.parse import urljoin
from django.db import models from django.db import models
@ -139,7 +139,7 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
def __str__(self): def __str__(self):
return f"Proxy Provider {self.name}" return f"Proxy Provider {self.name}"
def get_required_objects(self) -> Iterable[models.Model]: def get_required_objects(self) -> Iterable[Union[models.Model, str]]:
required_models = [self] required_models = [self]
if self.certificate is not None: if self.certificate is not None:
required_models.append(self.certificate) required_models.append(self.certificate)