refactor: Trust bridge API as a view set
This commit is contained in:
parent
0d3e1e3891
commit
1dfc868345
7 changed files with 71 additions and 70 deletions
|
@ -101,13 +101,6 @@ class User(PermissionsMixin, AbstractBaseUser):
|
|||
raise PasswordMismatch("The given password does not match the user's password.")
|
||||
return ldap.create_account(self.username, raw_password)
|
||||
|
||||
def get_or_create_trust_bridge(self):
|
||||
"""Returns a trust bridge instance. If it doesn't exist it is created."""
|
||||
try:
|
||||
return self.trust_bridge
|
||||
except TrustBridge.DoesNotExist:
|
||||
return TrustBridge.objects.create(trust_taker=self)
|
||||
|
||||
def get_primary_email(self):
|
||||
"""Returns the primary email address for this user."""
|
||||
return f"{self.username}@{settings.USERAUSFALL['PRIMARY_EMAIL_DOMAIN']}"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from userausfall.models import TrustBridge, User
|
||||
from userausfall.views import get_authenticated_user
|
||||
|
||||
|
||||
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||
|
@ -19,7 +20,7 @@ class TrustBridgeSerializer(serializers.HyperlinkedModelSerializer):
|
|||
fields = ["is_trusted", "trust_giver"]
|
||||
read_only_fields = ["is_trusted"]
|
||||
|
||||
def update(self, instance: TrustBridge, validated_data):
|
||||
instance.trust_giver, _ = User.objects.get_or_create(username=validated_data["trust_giver"]["username"])
|
||||
instance.save()
|
||||
return instance
|
||||
def create(self, validated_data):
|
||||
user = get_authenticated_user(self.context["request"])
|
||||
trust_giver, _ = User.objects.get_or_create(username=validated_data["trust_giver"]["username"])
|
||||
return TrustBridge.objects.create(trust_taker=user, trust_giver=trust_giver)
|
||||
|
|
|
@ -2,7 +2,29 @@ from rest_framework import status
|
|||
|
||||
from userausfall.models import User
|
||||
from userausfall.rest_api.tests.userausfall import UserausfallAPITestCase
|
||||
from userausfall.tests import UserMixin
|
||||
|
||||
|
||||
class UserMixin:
|
||||
user: User
|
||||
password: str
|
||||
username: str
|
||||
|
||||
def create_user(self):
|
||||
self.username = f"test{User.objects.count()}"
|
||||
self.password = "test12345"
|
||||
self.user = User.objects.create_user(self.username, self.password)
|
||||
return self.user
|
||||
|
||||
def ensure_user_exists(self):
|
||||
if not hasattr(self, "user"):
|
||||
self.create_user()
|
||||
|
||||
def authenticate_user(self):
|
||||
self.ensure_user_exists()
|
||||
if hasattr(self.client, "force_authentication"):
|
||||
self.client.force_authenticate(user=self.user)
|
||||
else:
|
||||
self.client.force_login(user=self.user)
|
||||
|
||||
|
||||
class UserTestCase(UserMixin, UserausfallAPITestCase):
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
from django.core import mail
|
||||
from rest_framework import status
|
||||
|
||||
from userausfall.rest_api.tests import UserausfallAPITestCase
|
||||
from userausfall.tests import UserMixin
|
||||
from userausfall.models import TrustBridge
|
||||
from userausfall.rest_api.tests import UserausfallAPITestCase, UserMixin
|
||||
|
||||
|
||||
class TrustBridgeTestCase(UserMixin, UserausfallAPITestCase):
|
||||
def test_retrieve_trust_bridge(self):
|
||||
"""Retrieve the trust bridge information of a user without an ldap account."""
|
||||
url = "/trust-bridge/"
|
||||
self.authenticate_user()
|
||||
response = self.client.get(self.get_api_url(url))
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(
|
||||
response.data,
|
||||
{
|
||||
"is_trusted": False,
|
||||
"trust_giver": None,
|
||||
},
|
||||
)
|
||||
def create_trust_bridge(self):
|
||||
self.trust_giver = self.create_user()
|
||||
self.create_user()
|
||||
self.trust_bridge = TrustBridge.objects.create(trust_taker=self.user, trust_giver=self.trust_giver)
|
||||
return self.trust_bridge
|
||||
|
||||
def test_update_trust_bridge(self):
|
||||
"""Update the trust giver of the user's trust bridge."""
|
||||
url = "/trust-bridge/"
|
||||
def test_create_trust_bridge(self):
|
||||
"""Create a trust bridge for the current user."""
|
||||
url = "/trust-bridges/"
|
||||
trust_giver = self.create_user()
|
||||
self.create_user()
|
||||
self.authenticate_user()
|
||||
response = self.client.put(
|
||||
response = self.client.post(
|
||||
self.get_api_url(url),
|
||||
{
|
||||
"trust_giver": {
|
||||
|
@ -34,16 +26,29 @@ class TrustBridgeTestCase(UserMixin, UserausfallAPITestCase):
|
|||
},
|
||||
},
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(TrustBridge.objects.count(), 1)
|
||||
self.assertEqual(TrustBridge.objects.get().trust_giver, trust_giver)
|
||||
|
||||
def test_retrieve_trust_bridge(self):
|
||||
"""Retrieve the trust bridge information of a user without an ldap account."""
|
||||
url = "/trust-bridges/{pk}/"
|
||||
self.create_trust_bridge()
|
||||
self.authenticate_user()
|
||||
response = self.client.get(self.get_api_url(url, pk=self.trust_bridge.pk))
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(self.user.trust_bridge.trust_giver, trust_giver)
|
||||
self.assertEqual(
|
||||
response.data,
|
||||
{
|
||||
"is_trusted": False,
|
||||
"trust_giver": {
|
||||
"username": self.trust_giver.username,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
def test_set_trust_giver(self):
|
||||
def test_send_confirmation_email_on_creation(self):
|
||||
"""When setting a trust giver a confirmation email is sent."""
|
||||
self.trust_giver = self.create_user()
|
||||
self.create_user()
|
||||
trust_bridge = self.user.get_or_create_trust_bridge()
|
||||
trust_bridge.trust_giver = self.trust_giver
|
||||
trust_bridge.save()
|
||||
|
||||
self.create_trust_bridge()
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertIn(self.user.trust_bridge.get_confirmation_token(), mail.outbox[0].body)
|
||||
|
|
|
@ -2,9 +2,10 @@ from django.urls import include, path
|
|||
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
|
||||
from rest_framework import routers
|
||||
|
||||
from userausfall.rest_api.views import TrustBridgeView
|
||||
from userausfall.rest_api.views import TrustBridgeViewSet
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r"trust-bridges", TrustBridgeViewSet, "trust-bridge")
|
||||
|
||||
urlpatterns = [
|
||||
path("", include(router.urls)),
|
||||
|
@ -12,5 +13,4 @@ urlpatterns = [
|
|||
path("schema/", SpectacularAPIView.as_view(), name="schema"),
|
||||
path("schema/swagger-ui/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"),
|
||||
path("schema/redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc"),
|
||||
path("trust-bridge/", TrustBridgeView.as_view()),
|
||||
]
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
from rest_framework import generics, status, viewsets
|
||||
from djeveric.views import ConfirmModelMixin
|
||||
from rest_framework import mixins, status, viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
|
||||
from userausfall.models import MissingUserAttribute, PasswordMismatch, User
|
||||
from userausfall.models import MissingUserAttribute, PasswordMismatch, TrustBridge, User
|
||||
from userausfall.rest_api.serializers import TrustBridgeSerializer
|
||||
from userausfall.views import get_authenticated_user
|
||||
|
||||
|
||||
class TrustBridgeView(generics.RetrieveUpdateAPIView):
|
||||
class TrustBridgeViewSet(
|
||||
ConfirmModelMixin, mixins.CreateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet
|
||||
):
|
||||
queryset = TrustBridge.objects
|
||||
serializer_class = TrustBridgeSerializer
|
||||
|
||||
def get_object(self):
|
||||
return get_authenticated_user(self.request).get_or_create_trust_bridge()
|
||||
def get_basic_queryset(self):
|
||||
return self.queryset.filter(trust_taker=get_authenticated_user(self.request))
|
||||
|
||||
|
||||
class UserViewSet(viewsets.GenericViewSet):
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
from userausfall.models import User
|
||||
|
||||
|
||||
class UserMixin:
|
||||
user: User
|
||||
password: str
|
||||
username: str
|
||||
|
||||
def create_user(self):
|
||||
self.username = f"test{User.objects.count()}"
|
||||
self.password = "test12345"
|
||||
self.user = User.objects.create_user(self.username, self.password)
|
||||
return self.user
|
||||
|
||||
def ensure_user_exists(self):
|
||||
if not hasattr(self, "user"):
|
||||
self.create_user()
|
||||
|
||||
def authenticate_user(self):
|
||||
self.ensure_user_exists()
|
||||
if hasattr(self.client, "force_authentication"):
|
||||
self.client.force_authenticate(user=self.user)
|
||||
else:
|
||||
self.client.force_login(user=self.user)
|
Reference in a new issue