From a887be1368bcc1dede4250e3083c9dbea996bd39 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 21 Oct 2021 10:29:37 +0200 Subject: [PATCH] refactor: Adapt python and settings to memoorje --- userausfall/confirmations.py | 18 -------- userausfall/emails.py | 4 +- userausfall/models.py | 2 +- userausfall/rest_api/permissions.py | 19 --------- userausfall/rest_api/urls.py | 15 +++---- userausfall/rest_api/views.py | 25 +---------- userausfall/settings.py | 65 ++++++++++++++++++++++------- userausfall/urls.py | 1 - 8 files changed, 61 insertions(+), 88 deletions(-) delete mode 100644 userausfall/confirmations.py delete mode 100644 userausfall/rest_api/permissions.py diff --git a/userausfall/confirmations.py b/userausfall/confirmations.py deleted file mode 100644 index 53cb480..0000000 --- a/userausfall/confirmations.py +++ /dev/null @@ -1,18 +0,0 @@ -from djeveric import Confirmation - -from userausfall.emails import ConfidantConfirmationEmail -from userausfall.models import User - - -class ConfidantConfirmation(Confirmation): - email_class = ConfidantConfirmationEmail - - def has_permission(self, user: User, resource: User): - return user == resource.confidant_unconfirmed - - def is_confirmed(self, resource: User): - return resource.confidant_unconfirmed == resource.confidant - - def confirm(self, resource: User): - resource.confidant = resource.confidant_unconfirmed - resource.save() diff --git a/userausfall/emails.py b/userausfall/emails.py index 2d4d632..45efdd2 100644 --- a/userausfall/emails.py +++ b/userausfall/emails.py @@ -1,7 +1,7 @@ -from djeveric import Email +from djeveric.emails import ConfirmationEmail -class ConfidantConfirmationEmail(Email): +class ConfidantConfirmationEmail(ConfirmationEmail): subject = "TODO" def get_message(self, context): diff --git a/userausfall/models.py b/userausfall/models.py index 59587ca..7331b19 100644 --- a/userausfall/models.py +++ b/userausfall/models.py @@ -52,7 +52,7 @@ class UserManager(BaseUserManager): return self._create_user(email, password, **extra_fields) -class User(AbstractBaseUser, PermissionsMixin): +class User(PermissionsMixin, AbstractBaseUser): username_validator = UnicodeUsernameValidator() username = models.CharField( diff --git a/userausfall/rest_api/permissions.py b/userausfall/rest_api/permissions.py deleted file mode 100644 index 0291279..0000000 --- a/userausfall/rest_api/permissions.py +++ /dev/null @@ -1,19 +0,0 @@ -from rest_framework import permissions - - -class UserPermission(permissions.BasePermission): - def has_permission(self, request, view): - result = False - if view.action == "activate": - result = True - elif view.action == "create": - result = True - elif view.action == "retrieve_authenticated": - result = request.user.is_authenticated - return result - - def has_object_permission(self, request, view, obj): - result = False - if view.action == "activate": - result = request.user == obj - return result diff --git a/userausfall/rest_api/urls.py b/userausfall/rest_api/urls.py index c3a2ff6..a3a4ed8 100644 --- a/userausfall/rest_api/urls.py +++ b/userausfall/rest_api/urls.py @@ -1,12 +1,13 @@ +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 UserViewSet - -router = routers.DefaultRouter(trailing_slash=True) -router.register(r"users", UserViewSet, basename="user") +router = routers.SimpleRouter() urlpatterns = [ - # path("confirm/confidant/", ConfidantConfirmationView.as_view()) + path("", include(router.urls)), + path("auth/", include("rest_registration.api.urls")), + 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"), ] - -urlpatterns += router.urls diff --git a/userausfall/rest_api/views.py b/userausfall/rest_api/views.py index 0f3f4c0..b64d9eb 100644 --- a/userausfall/rest_api/views.py +++ b/userausfall/rest_api/views.py @@ -3,24 +3,9 @@ from rest_framework.decorators import action from rest_framework.response import Response from userausfall.models import MissingUserAttribute, PasswordMismatch, User -from userausfall.rest_api.permissions import UserPermission -from userausfall.rest_api.serializers import ( - ActivateUserSerializer, - CreateUserSerializer, - RetrieveUserSerializer, -) -class UserViewSet(viewsets.ModelViewSet): - permission_classes = [UserPermission] - queryset = User.objects.all() - - @action(detail=False, url_path="me") - def retrieve_authenticated(self, request): - """Retrieve user data for logged in user.""" - serializer = self.get_serializer(request.user) - return Response(serializer.data) - +class UserViewSet(viewsets.GenericViewSet): @action(detail=True, methods=["post"]) def activate(self, request, pk=None): """Create the corresponding LDAP account.""" @@ -38,11 +23,3 @@ class UserViewSet(viewsets.ModelViewSet): return Response(status=status.HTTP_204_NO_CONTENT) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - def get_serializer_class(self): - if self.action == "activate": - return ActivateUserSerializer - elif self.action == "create": - return CreateUserSerializer - elif self.action == "retrieve_authenticated": - return RetrieveUserSerializer diff --git a/userausfall/settings.py b/userausfall/settings.py index eeed203..5fb82af 100644 --- a/userausfall/settings.py +++ b/userausfall/settings.py @@ -38,8 +38,12 @@ INSTALLED_APPS = [ "django.contrib.messages", "django.contrib.sites", "django.contrib.staticfiles", - "userausfall", "rest_framework", + "rest_registration", + "django_filters", + "drf_spectacular", + "userausfall", + "userausfall.rest_api", ] MIDDLEWARE = [ @@ -79,23 +83,11 @@ WSGI_APPLICATION = "userausfall.wsgi.application" DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", - "NAME": os.path.join(DATA_DIR, "db.sqlite3"), + "NAME": DATA_DIR / "db.sqlite3", } } -# Default primary key field type -# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" - - -# User model -# - -AUTH_USER_MODEL = "userausfall.User" - - # Password validation # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators @@ -138,11 +130,23 @@ STATIC_URL = "/static/" # Media files # https://docs.djangoproject.com/en/2.2/topics/files/ -MEDIA_ROOT = os.path.join(BASE_DIR, "media") +MEDIA_ROOT = DATA_DIR / "media" MEDIA_URL = "/media/" +# Default primary key field type +# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + + +# User model +# + +AUTH_USER_MODEL = "userausfall.User" + + # Sending email # https://docs.djangoproject.com/en/3.2/topics/email/ @@ -153,7 +157,36 @@ EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" # https://www.django-rest-framework.org/api-guide/settings/ REST_FRAMEWORK = { - "DEFAULT_AUTHENTICATION_CLASSES": ("rest_framework.authentication.SessionAuthentication",), + "DEFAULT_FILTER_BACKENDS": [ + "django_filters.rest_framework.DjangoFilterBackend", + ], + "DEFAULT_PARSER_CLASSES": [ + "djangorestframework_camel_case.parser.CamelCaseFormParser", + "djangorestframework_camel_case.parser.CamelCaseMultiPartParser", + "djangorestframework_camel_case.parser.CamelCaseJSONParser", + ], + "DEFAULT_PERMISSION_CLASSES": [ + "rest_framework.permissions.IsAuthenticated", + ], + "DEFAULT_RENDERER_CLASSES": [ + "djangorestframework_camel_case.render.CamelCaseJSONRenderer", + "djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer", + ], + "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + "TEST_REQUEST_DEFAULT_FORMAT": "json", +} + +REST_REGISTRATION = { + "REGISTER_VERIFICATION_ENABLED": False, + "REGISTER_EMAIL_VERIFICATION_ENABLED": False, + "RESET_PASSWORD_VERIFICATION_ENABLED": False, +} + +SPECTACULAR_SETTINGS = { + "TITLE": "Userausfall API", + "DESCRIPTION": "Account management for systemausfall.org", + "VERSION": "0.0.1", + "POSTPROCESSING_HOOKS": ["drf_spectacular.contrib.djangorestframework_camel_case.camelize_serializer_fields"], } diff --git a/userausfall/urls.py b/userausfall/urls.py index 252cfbf..575221f 100644 --- a/userausfall/urls.py +++ b/userausfall/urls.py @@ -4,5 +4,4 @@ from django.urls import include, path urlpatterns = [ path("admin/", admin.site.urls), path("api/", include("userausfall.rest_api.urls")), - path("api-auth/", include("rest_framework.urls")), ]