Support session/cookie based auth, see #1108

This commit is contained in:
Agate 2020-05-18 12:03:30 +02:00
commit 550dbe46cc
14 changed files with 172 additions and 62 deletions

View file

@ -1,8 +1,11 @@
from django.conf.urls import url
from funkwhale_api.common import routers
from . import views
router = routers.OptionalSlashRouter()
router.register(r"users", views.UserViewSet, "users")
urlpatterns = router.urls
urlpatterns = [
url(r"^users/login/?$", views.login, name="login"),
url(r"^users/logout/?$", views.logout, name="logout"),
] + router.urls

View file

@ -4,6 +4,8 @@ from django.core import validators
from django.utils.deconstruct import deconstructible
from django.utils.translation import gettext_lazy as _
from django.contrib import auth
from rest_auth.serializers import PasswordResetSerializer as PRS
from rest_auth.registration.serializers import RegisterSerializer as RS, get_adapter
from rest_framework import serializers
@ -265,3 +267,23 @@ class UserDeleteSerializer(serializers.Serializer):
if not value:
raise serializers.ValidationError("Please confirm deletion")
return value
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
user = auth.authenticate(request=self.context.get("request"), **data)
if not user:
raise serializers.ValidationError(
"Unable to log in with provided credentials"
)
if not user.is_active:
raise serializers.ValidationError("This account was disabled")
return user
def save(self, request):
return auth.login(request, self.validated_data)

View file

@ -1,12 +1,20 @@
import json
from django import http
from django.contrib import auth
from django.middleware import csrf
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
from rest_framework import mixins, viewsets
from rest_framework import mixins
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from funkwhale_api.common import authentication
from funkwhale_api.common import preferences
from funkwhale_api.common import throttling
from . import models, serializers, tasks
@ -105,3 +113,26 @@ class UserViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
if not self.request.user.username == kwargs.get("username"):
return Response(status=403)
return super().partial_update(request, *args, **kwargs)
def login(request):
throttling.check_request(request, "login")
if request.method != "POST":
return http.HttpResponse(status=405)
serializer = serializers.LoginSerializer(
data=request.POST, context={"request": request}
)
if not serializer.is_valid():
return http.HttpResponse(
json.dumps(serializer.errors), status=400, content_type="application/json"
)
serializer.save(request)
csrf.rotate_token(request)
return http.HttpResponse(status=200)
def logout(request):
if request.method != "POST":
return http.HttpResponse(status=405)
auth.logout(request)
return http.HttpResponse(status=200)