From 22f0b1a2d835f476672bb927a94e8a7128fbdae5 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Sun, 6 May 2018 11:30:41 +0200
Subject: [PATCH] See #187: API logic for password reset

---
 api/config/settings/common.py             |  5 +++++
 api/funkwhale_api/users/rest_auth_urls.py | 16 ++++++++++------
 api/funkwhale_api/users/serializers.py    | 13 ++++++++++++-
 api/tests/users/test_views.py             | 14 ++++++++++++++
 4 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index 2e9421e794..9c5487d64b 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -391,6 +391,11 @@ REST_FRAMEWORK = {
         'django_filters.rest_framework.DjangoFilterBackend',
     )
 }
+REST_AUTH_SERIALIZERS = {
+    'PASSWORD_RESET_SERIALIZER': 'funkwhale_api.users.serializers.PasswordResetSerializer'  # noqa
+}
+REST_SESSION_LOGIN = False
+REST_USE_JWT = True
 
 ATOMIC_REQUESTS = False
 USE_X_FORWARDED_HOST = True
diff --git a/api/funkwhale_api/users/rest_auth_urls.py b/api/funkwhale_api/users/rest_auth_urls.py
index 31f5384aa7..fa6c425cc5 100644
--- a/api/funkwhale_api/users/rest_auth_urls.py
+++ b/api/funkwhale_api/users/rest_auth_urls.py
@@ -1,16 +1,20 @@
 from django.views.generic import TemplateView
 from django.conf.urls import url
 
-from rest_auth.registration.views import VerifyEmailView
-from rest_auth.views import PasswordChangeView
+from rest_auth.registration import views as registration_views
+from rest_auth import views as rest_auth_views
 
-from .views import RegisterView
+from . import views
 
 
 urlpatterns = [
-    url(r'^$', RegisterView.as_view(), name='rest_register'),
-    url(r'^verify-email/$', VerifyEmailView.as_view(), name='rest_verify_email'),
-    url(r'^change-password/$', PasswordChangeView.as_view(), name='change_password'),
+    url(r'^$', views.RegisterView.as_view(), name='rest_register'),
+    url(r'^verify-email/$',
+        registration_views.VerifyEmailView.as_view(),
+        name='rest_verify_email'),
+    url(r'^change-password/$',
+        rest_auth_views.PasswordChangeView.as_view(),
+        name='change_password'),
 
     # This url is used by django-allauth and empty TemplateView is
     # defined just to allow reverse() call inside app, for example when email
diff --git a/api/funkwhale_api/users/serializers.py b/api/funkwhale_api/users/serializers.py
index b21aa69355..eadce6154f 100644
--- a/api/funkwhale_api/users/serializers.py
+++ b/api/funkwhale_api/users/serializers.py
@@ -1,5 +1,7 @@
-from rest_framework import serializers
+from django.conf import settings
 
+from rest_framework import serializers
+from rest_auth.serializers import PasswordResetSerializer as PRS
 from funkwhale_api.activity import serializers as activity_serializers
 
 from . import models
@@ -63,3 +65,12 @@ class UserReadSerializer(serializers.ModelSerializer):
                 'status': o.has_perm(internal_codename)
             }
         return perms
+
+
+class PasswordResetSerializer(PRS):
+    def get_email_options(self):
+        return {
+            'extra_email_context': {
+                'funkwhale_url': settings.FUNKWHALE_URL
+            }
+        }
diff --git a/api/tests/users/test_views.py b/api/tests/users/test_views.py
index 4be586965f..985a78c8a6 100644
--- a/api/tests/users/test_views.py
+++ b/api/tests/users/test_views.py
@@ -136,6 +136,20 @@ def test_changing_password_updates_secret_key(logged_in_client):
     assert user.password != password
 
 
+def test_can_request_password_reset(
+        factories, api_client, mailoutbox):
+    user = factories['users.User']()
+    payload = {
+        'email': user.email,
+    }
+    emails = len(mailoutbox)
+    url = reverse('rest_password_reset')
+
+    response = api_client.post(url, payload)
+    assert response.status_code == 200
+    assert len(mailoutbox) > emails
+
+
 def test_user_can_patch_his_own_settings(logged_in_api_client):
     user = logged_in_api_client.user
     payload = {
-- 
GitLab