Compare commits

...

2 commits

10 changed files with 115 additions and 25 deletions

View file

@ -0,0 +1,28 @@
# Generated by Django 3.2.8 on 2021-10-21 09:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('userausfall', '0011_trustbridge'),
]
operations = [
migrations.RenameField(
model_name='trustbridge',
old_name='user',
new_name='trust_taker',
),
migrations.AlterField(
model_name='trustbridge',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='user',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View file

@ -0,0 +1,20 @@
# Generated by Django 3.2.8 on 2021-10-21 09:04
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('userausfall', '0012_auto_20211021_0901'),
]
operations = [
migrations.AddField(
model_name='trustbridge',
name='trust_giver',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
]

View file

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

View file

@ -1,30 +1,10 @@
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"]
read_only_fields = ["is_trusted"]

View file

@ -1 +1,2 @@
from .auth import * # noqa: F401, F403
from .trust_bridges import * # noqa: F401, F403

View file

@ -0,0 +1,34 @@
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,
},
)
def test_update_trust_bridge(self):
"""
Update the trust giver of the user's trust bridge.
"""
url = "/trust-bridge/"
other_user = self.create_user()
self.create_user()
self.authenticate_user()
response = self.client.put(self.get_api_url(url), {"trust_giver": other_user.pk})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.user.trust_bridge.trust_giver, other_user)

View file

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

View file

@ -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.RetrieveUpdateAPIView):
serializer_class = TrustBridgeSerializer
def get_object(self):
return get_authenticated_user(self.request).get_or_create_trust_bridge()
class UserViewSet(viewsets.GenericViewSet):

View file

@ -10,6 +10,7 @@ class UserMixin:
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"):

7
userausfall/views.py Normal file
View file

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