diff --git a/userausfall/models.py b/userausfall/models.py index 7331b19..dbeaca5 100644 --- a/userausfall/models.py +++ b/userausfall/models.py @@ -97,7 +97,14 @@ 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): + try: + return self.trust_bridge + except TrustBridge.DoesNotExist: + return TrustBridge.objects.create(trust_taker=self) + class TrustBridge(models.Model): - user = models.OneToOneField("User", on_delete=models.CASCADE, related_name="trust_bridge") is_trusted = models.BooleanField(default=False) + trust_giver = models.ForeignKey("User", on_delete=models.SET_NULL, null=True) + trust_taker = models.OneToOneField("User", on_delete=models.CASCADE, related_name="trust_bridge") diff --git a/userausfall/rest_api/serializers.py b/userausfall/rest_api/serializers.py index a9a6479..92d2f9e 100644 --- a/userausfall/rest_api/serializers.py +++ b/userausfall/rest_api/serializers.py @@ -1,30 +1,9 @@ from rest_framework import serializers -from userausfall.models import TrustBridge, User +from userausfall.models import TrustBridge class TrustBridgeSerializer(serializers.ModelSerializer): class Meta: model = TrustBridge - fields = ["is_trusted"] - - -class ActivateUserSerializer(serializers.Serializer): - password = serializers.CharField() - - -class RetrieveUserSerializer(serializers.ModelSerializer): - trust_bridge = TrustBridgeSerializer(required=False, read_only=True) - - class Meta: - model = User - fields = ["pk", "username", "trust_bridge"] - - -class CreateUserSerializer(serializers.ModelSerializer): - class Meta: - model = User - fields = ("username", "password") - - def create(self, validated_data): - return User.objects.create_user(**validated_data) + fields = ["is_trusted", "trust_giver"] diff --git a/userausfall/rest_api/tests/__init__.py b/userausfall/rest_api/tests/__init__.py index 78ced3d..f7cf7fe 100644 --- a/userausfall/rest_api/tests/__init__.py +++ b/userausfall/rest_api/tests/__init__.py @@ -1 +1,2 @@ from .auth import * # noqa: F401, F403 +from .trust_bridges import * # noqa: F401, F403 diff --git a/userausfall/rest_api/tests/trust_bridges.py b/userausfall/rest_api/tests/trust_bridges.py new file mode 100644 index 0000000..24a7f9c --- /dev/null +++ b/userausfall/rest_api/tests/trust_bridges.py @@ -0,0 +1,22 @@ +from rest_framework import status + +from userausfall.rest_api.tests import UserausfallAPITestCase +from userausfall.tests import 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, + }, + ) diff --git a/userausfall/rest_api/urls.py b/userausfall/rest_api/urls.py index a3a4ed8..0d476a2 100644 --- a/userausfall/rest_api/urls.py +++ b/userausfall/rest_api/urls.py @@ -2,6 +2,8 @@ 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 + router = routers.SimpleRouter() urlpatterns = [ @@ -10,4 +12,5 @@ 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()), ] diff --git a/userausfall/rest_api/views.py b/userausfall/rest_api/views.py index b64d9eb..f6bf7da 100644 --- a/userausfall/rest_api/views.py +++ b/userausfall/rest_api/views.py @@ -1,8 +1,17 @@ -from rest_framework import status, viewsets +from rest_framework import generics, status, viewsets from rest_framework.decorators import action from rest_framework.response import Response from userausfall.models import MissingUserAttribute, PasswordMismatch, User +from userausfall.rest_api.serializers import TrustBridgeSerializer +from userausfall.views import get_authenticated_user + + +class TrustBridgeView(generics.RetrieveAPIView): + serializer_class = TrustBridgeSerializer + + def get_object(self): + return get_authenticated_user(self.request).get_or_create_trust_bridge() class UserViewSet(viewsets.GenericViewSet): diff --git a/userausfall/views.py b/userausfall/views.py new file mode 100644 index 0000000..4552667 --- /dev/null +++ b/userausfall/views.py @@ -0,0 +1,7 @@ +from userausfall.models import User + + +def get_authenticated_user(request) -> User: + if request is not None and request.user.is_authenticated: + return request.user + return None