Skip to content
Snippets Groups Projects
views.py 4.14 KiB
Newer Older
  • Learn to ignore specific revisions
  • from allauth.account.adapter import get_adapter
    
    from rest_auth import views as rest_auth_views
    from rest_auth.registration import views as registration_views
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from rest_framework import mixins, viewsets
    
    from rest_framework.decorators import action
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from rest_framework.response import Response
    
    from funkwhale_api.common import authentication
    
    from funkwhale_api.common import preferences
    
    
    from . import models, serializers, tasks
    
    class RegisterView(registration_views.RegisterView):
    
        serializer_class = serializers.RegisterSerializer
    
        permission_classes = []
    
        action = "signup"
        throttling_scopes = {"signup": {"authenticated": "signup", "anonymous": "signup"}}
    
        def create(self, request, *args, **kwargs):
    
            invitation_code = request.data.get("invitation")
            if not invitation_code and not self.is_open_for_signup(request):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                r = {"detail": "Registration has been disabled"}
    
                return Response(r, status=403)
            return super().create(request, *args, **kwargs)
    
        def is_open_for_signup(self, request):
            return get_adapter().is_open_for_signup(request)
    
    
        def perform_create(self, serializer):
            user = super().perform_create(serializer)
            if not user.is_active:
                # manual approval, we need to send the confirmation email by hand
                authentication.send_email_confirmation(self.request, user)
            return user
    
    
    class VerifyEmailView(registration_views.VerifyEmailView):
        action = "verify-email"
    
    
    class PasswordChangeView(rest_auth_views.PasswordChangeView):
        action = "password-change"
    
    
    class PasswordResetView(rest_auth_views.PasswordResetView):
        action = "password-reset"
    
    
    class PasswordResetConfirmView(rest_auth_views.PasswordResetConfirmView):
        action = "password-reset-confirm"
    
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    class UserViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        queryset = models.User.objects.all().select_related("actor__attachment_icon")
    
        serializer_class = serializers.UserWriteSerializer
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        lookup_field = "username"
    
        required_scope = "profile"
    
        @action(methods=["get", "delete"], detail=False)
    
        def me(self, request, *args, **kwargs):
    
            """Return information about the current user or delete it"""
            if request.method.lower() == "delete":
                serializer = serializers.UserDeleteSerializer(
                    request.user, data=request.data
                )
                serializer.is_valid(raise_exception=True)
                tasks.delete_account.delay(user_id=request.user.pk)
                # at this point, password is valid, we launch deletion
                return Response(status=204)
    
            serializer = serializers.MeSerializer(request.user)
    
        @action(
            methods=["get", "post", "delete"],
            required_scope="security",
            url_path="subsonic-token",
            detail=True,
        )
    
        def subsonic_token(self, request, *args, **kwargs):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if not self.request.user.username == kwargs.get("username"):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if not preferences.get("subsonic__enabled"):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if request.method.lower() == "get":
                return Response(
                    {"subsonic_api_token": self.request.user.subsonic_api_token}
                )
            if request.method.lower() == "delete":
    
                self.request.user.subsonic_api_token = None
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                self.request.user.save(update_fields=["subsonic_api_token"])
    
                return Response(status=204)
            self.request.user.update_subsonic_api_token()
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            self.request.user.save(update_fields=["subsonic_api_token"])
            data = {"subsonic_api_token": self.request.user.subsonic_api_token}
    
        def update(self, request, *args, **kwargs):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if not self.request.user.username == kwargs.get("username"):
    
                return Response(status=403)
            return super().update(request, *args, **kwargs)
    
        def partial_update(self, request, *args, **kwargs):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if not self.request.user.username == kwargs.get("username"):
    
                return Response(status=403)
            return super().partial_update(request, *args, **kwargs)