refactor: Trust bridge API as a view set

This commit is contained in:
aldrin 2021-10-22 11:43:33 +02:00
parent 0d3e1e3891
commit 1dfc868345
7 changed files with 71 additions and 70 deletions

View File

@ -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']}"

View File

@ -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)

View File

@ -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):

View File

@ -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)

View File

@ -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()),
]

View File

@ -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):

View File

@ -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)