refactor: Adapt python and settings to memoorje
This commit is contained in:
parent
ceb032dddb
commit
a887be1368
8 changed files with 61 additions and 88 deletions
|
@ -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()
|
|
|
@ -1,7 +1,7 @@
|
||||||
from djeveric import Email
|
from djeveric.emails import ConfirmationEmail
|
||||||
|
|
||||||
|
|
||||||
class ConfidantConfirmationEmail(Email):
|
class ConfidantConfirmationEmail(ConfirmationEmail):
|
||||||
subject = "TODO"
|
subject = "TODO"
|
||||||
|
|
||||||
def get_message(self, context):
|
def get_message(self, context):
|
||||||
|
|
|
@ -52,7 +52,7 @@ class UserManager(BaseUserManager):
|
||||||
return self._create_user(email, password, **extra_fields)
|
return self._create_user(email, password, **extra_fields)
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser, PermissionsMixin):
|
class User(PermissionsMixin, AbstractBaseUser):
|
||||||
username_validator = UnicodeUsernameValidator()
|
username_validator = UnicodeUsernameValidator()
|
||||||
|
|
||||||
username = models.CharField(
|
username = models.CharField(
|
||||||
|
|
|
@ -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
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
from django.urls import include, path
|
||||||
|
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
from userausfall.rest_api.views import UserViewSet
|
router = routers.SimpleRouter()
|
||||||
|
|
||||||
router = routers.DefaultRouter(trailing_slash=True)
|
|
||||||
router.register(r"users", UserViewSet, basename="user")
|
|
||||||
|
|
||||||
urlpatterns = [
|
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
|
|
||||||
|
|
|
@ -3,24 +3,9 @@ from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from userausfall.models import MissingUserAttribute, PasswordMismatch, User
|
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):
|
class UserViewSet(viewsets.GenericViewSet):
|
||||||
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)
|
|
||||||
|
|
||||||
@action(detail=True, methods=["post"])
|
@action(detail=True, methods=["post"])
|
||||||
def activate(self, request, pk=None):
|
def activate(self, request, pk=None):
|
||||||
"""Create the corresponding LDAP account."""
|
"""Create the corresponding LDAP account."""
|
||||||
|
@ -38,11 +23,3 @@ class UserViewSet(viewsets.ModelViewSet):
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
else:
|
else:
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
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
|
|
||||||
|
|
|
@ -38,8 +38,12 @@ INSTALLED_APPS = [
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.sites",
|
"django.contrib.sites",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"userausfall",
|
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
|
"rest_registration",
|
||||||
|
"django_filters",
|
||||||
|
"drf_spectacular",
|
||||||
|
"userausfall",
|
||||||
|
"userausfall.rest_api",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -79,23 +83,11 @@ WSGI_APPLICATION = "userausfall.wsgi.application"
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
"default": {
|
"default": {
|
||||||
"ENGINE": "django.db.backends.sqlite3",
|
"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
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
@ -138,11 +130,23 @@ STATIC_URL = "/static/"
|
||||||
# Media files
|
# Media files
|
||||||
# https://docs.djangoproject.com/en/2.2/topics/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/"
|
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
|
# Sending email
|
||||||
# https://docs.djangoproject.com/en/3.2/topics/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/
|
# https://www.django-rest-framework.org/api-guide/settings/
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
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"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,4 @@ from django.urls import include, path
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("api/", include("userausfall.rest_api.urls")),
|
path("api/", include("userausfall.rest_api.urls")),
|
||||||
path("api-auth/", include("rest_framework.urls")),
|
|
||||||
]
|
]
|
||||||
|
|
Reference in a new issue