diff --git a/passbook/core/templates/base/skeleton.html b/passbook/core/templates/base/skeleton.html index 303dbffd7..68f9c158e 100644 --- a/passbook/core/templates/base/skeleton.html +++ b/passbook/core/templates/base/skeleton.html @@ -6,8 +6,8 @@ - - + + {% block title %}{% trans title|default:config.passbook.branding.title %}{% endblock %} diff --git a/passbook/outposts/models.py b/passbook/outposts/models.py index b461838d7..9ebd90bc9 100644 --- a/passbook/outposts/models.py +++ b/passbook/outposts/models.py @@ -7,9 +7,10 @@ from uuid import uuid4 from dacite import from_dict from django.contrib.postgres.fields import ArrayField from django.core.cache import cache -from django.db import models +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 from guardian.shortcuts import assign_perm from passbook.core.models import Provider, Token, TokenIntents, User @@ -114,10 +115,13 @@ class Outpost(models.Model): user.save() else: user = users.first() - for model in self.get_required_objects(): - assign_perm( - f"{model._meta.app_label}.view_{model._meta.model_name}", user, model - ) + # To ensure the user only has the correct permissions, we delete all of them and re-add + # the ones the user needs + with transaction.atomic(): + UserObjectPermission.objects.filter(user=user).delete() + for model in self.get_required_objects(): + code_name = f"{model._meta.app_label}.view_{model._meta.model_name}" + assign_perm(code_name, user, model) return user @property diff --git a/passbook/outposts/tests.py b/passbook/outposts/tests.py new file mode 100644 index 000000000..18675e4c0 --- /dev/null +++ b/passbook/outposts/tests.py @@ -0,0 +1,60 @@ +"""outpost tests""" +from django.test import TestCase +from guardian.models import UserObjectPermission + +from passbook.crypto.models import CertificateKeyPair +from passbook.flows.models import Flow +from passbook.outposts.models import Outpost, OutpostDeploymentType, OutpostType +from passbook.providers.proxy.models import ProxyProvider + + +class OutpostTests(TestCase): + """Outpost Tests""" + + def test_service_account_permissions(self): + """Test that the service account has correct permissions""" + provider: ProxyProvider = ProxyProvider.objects.create( + name="test", + internal_host="http://localhost", + external_host="http://localhost", + authorization_flow=Flow.objects.first(), + ) + outpost: Outpost = Outpost.objects.create( + name="test", + type=OutpostType.PROXY, + deployment_type=OutpostDeploymentType.CUSTOM, + ) + + # Before we add a provider, the user should only have access to the outpost + permissions = UserObjectPermission.objects.filter(user=outpost.user) + self.assertEqual(len(permissions), 1) + self.assertEqual(permissions[0].object_pk, str(outpost.pk)) + + # We add a provider, user should only have access to outpost and provider + outpost.providers.add(provider) + outpost.save() + permissions = UserObjectPermission.objects.filter(user=outpost.user).order_by( + "content_type__model" + ) + self.assertEqual(len(permissions), 2) + self.assertEqual(permissions[0].object_pk, str(outpost.pk)) + self.assertEqual(permissions[1].object_pk, str(provider.pk)) + + # Provider requires a certificate-key-pair, user should have permissions for it + keypair = CertificateKeyPair.objects.first() + provider.certificate = keypair + provider.save() + permissions = UserObjectPermission.objects.filter(user=outpost.user).order_by( + "content_type__model" + ) + self.assertEqual(len(permissions), 3) + self.assertEqual(permissions[0].object_pk, str(keypair.pk)) + self.assertEqual(permissions[1].object_pk, str(outpost.pk)) + self.assertEqual(permissions[2].object_pk, str(provider.pk)) + + # Remove provider from outpost, user should only have access to outpost + outpost.providers.remove(provider) + outpost.save() + permissions = UserObjectPermission.objects.filter(user=outpost.user) + self.assertEqual(len(permissions), 1) + self.assertEqual(permissions[0].object_pk, str(outpost.pk))