outposts: don't always build permissions on outpost.user access, only in signals and tasks

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-10-04 18:04:19 +02:00
parent 9778050dda
commit fab9a10487
3 changed files with 23 additions and 16 deletions

View File

@ -341,19 +341,8 @@ class Outpost(ManagedModel):
"""Username for service user""" """Username for service user"""
return f"ak-outpost-{self.uuid.hex}" return f"ak-outpost-{self.uuid.hex}"
@property def build_user_permissions(self, user: User):
def user(self) -> User: """Create per-object and global permissions for outpost service-account"""
"""Get/create user with access to all required objects"""
users = User.objects.filter(username=self.user_identifier)
if not users.exists():
user: User = User.objects.create(username=self.user_identifier)
user.set_unusable_password()
user.save()
else:
user = users.first()
user.attributes[USER_ATTRIBUTE_SA] = True
user.attributes[USER_ATTRIBUTE_CAN_OVERRIDE_IP] = True
user.save()
# To ensure the user only has the correct permissions, we delete all of them and re-add # To ensure the user only has the correct permissions, we delete all of them and re-add
# the ones the user needs # the ones the user needs
with transaction.atomic(): with transaction.atomic():
@ -397,6 +386,23 @@ class Outpost(ManagedModel):
"Updated service account's permissions", "Updated service account's permissions",
perms=UserObjectPermission.objects.filter(user=user), perms=UserObjectPermission.objects.filter(user=user),
) )
@property
def user(self) -> User:
"""Get/create user with access to all required objects"""
users = User.objects.filter(username=self.user_identifier)
should_create_user = not users.exists()
if should_create_user:
user: User = User.objects.create(username=self.user_identifier)
user.set_unusable_password()
user.save()
else:
user = users.first()
user.attributes[USER_ATTRIBUTE_SA] = True
user.attributes[USER_ATTRIBUTE_CAN_OVERRIDE_IP] = True
user.save()
if should_create_user:
self.build_user_permissions(user)
return user return user
@property @property

View File

@ -126,6 +126,7 @@ def outpost_token_ensurer(self: MonitoredTask):
all_outposts = Outpost.objects.all() all_outposts = Outpost.objects.all()
for outpost in all_outposts: for outpost in all_outposts:
_ = outpost.token _ = outpost.token
outpost.build_user_permissions(outpost.user)
self.set_status( self.set_status(
TaskResult( TaskResult(
TaskResultStatus.SUCCESSFUL, TaskResultStatus.SUCCESSFUL,
@ -196,7 +197,7 @@ def _outpost_single_update(outpost: Outpost, layer=None):
# Ensure token again, because this function is called when anything related to an # Ensure token again, because this function is called when anything related to an
# OutpostModel is saved, so we can be sure permissions are right # OutpostModel is saved, so we can be sure permissions are right
_ = outpost.token _ = outpost.token
_ = outpost.user outpost.build_user_permissions(outpost.user)
if not layer: # pragma: no cover if not layer: # pragma: no cover
layer = get_channel_layer() layer = get_channel_layer()
for state in OutpostState.for_outpost(outpost): for state in OutpostState.for_outpost(outpost):

View File

@ -86,7 +86,7 @@ class TestProviderProxy(SeleniumTestCase):
) )
outpost.providers.add(proxy) outpost.providers.add(proxy)
outpost.save() outpost.save()
_ = outpost.user outpost.build_user_permissions(outpost.user)
self.proxy_container = self.start_proxy(outpost) self.proxy_container = self.start_proxy(outpost)
@ -150,7 +150,7 @@ class TestProviderProxyConnect(ChannelsLiveServerTestCase):
) )
outpost.providers.add(proxy) outpost.providers.add(proxy)
outpost.save() outpost.save()
_ = outpost.user outpost.build_user_permissions(outpost.user)
# Wait until outpost healthcheck succeeds # Wait until outpost healthcheck succeeds
healthcheck_retries = 0 healthcheck_retries = 0