Skip to content

Commit a4ead90

Browse files
authored
Merge pull request #123 from anx-bhagmann/browsable-api
Add helper function to extend django-drf browsable API with passwordr…
2 parents 137d140 + b7c1b3b commit a4ead90

File tree

3 files changed

+98
-10
lines changed

3 files changed

+98
-10
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,39 @@ django-rest-passwordreset Version | Django Versions | Django Rest Framework Vers
274274

275275
This package supports the [DRF auto-generated documentation](https://www.django-rest-framework.org/topics/documenting-your-api/) (via `coreapi`) as well as the [DRF browsable API](https://www.django-rest-framework.org/topics/browsable-api/).
276276

277+
To add the endpoints to the browsable API, you can use a helper function in your `urls.py` file:
278+
```python
279+
from rest_framework.routers import DefaultRouter
280+
from django_rest_passwordreset.urls import add_reset_password_urls_to_router
281+
282+
router = DefaultRouter()
283+
add_reset_password_urls_to_router(router, base_path='api/auth/passwordreset')
284+
```
285+
286+
Alternatively you can import the ViewSets manually and customize the routes for your setup:
287+
```python
288+
from rest_framework.routers import DefaultRouter
289+
from django_rest_passwordreset.views import ResetPasswordValidateTokenViewSet, ResetPasswordConfirmViewSet, \
290+
ResetPasswordRequestTokenViewSet
291+
292+
router = DefaultRouter()
293+
router.register(
294+
r'api/auth/passwordreset/validate_token',
295+
ResetPasswordValidateTokenViewSet,
296+
basename='reset-password-validate'
297+
)
298+
router.register(
299+
r'api/auth/passwordreset/confirm',
300+
ResetPasswordConfirmViewSet,
301+
basename='reset-password-confirm'
302+
)
303+
router.register(
304+
r'api/auth/passwordreset/',
305+
ResetPasswordRequestTokenViewSet,
306+
basename='reset-password-request'
307+
)
308+
```
309+
277310
![drf_browsable_email_validation](docs/browsable_api_email_validation.png "Browsable API E-Mail Validation")
278311

279312
![drf_browsable_password_validation](docs/browsable_api_password_validation.png "Browsable API E-Mail Validation")

django_rest_passwordreset/urls.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1-
""" URL Configuration for core auth
2-
"""
3-
from django.conf.urls import url, include
4-
from django_rest_passwordreset.views import reset_password_request_token, reset_password_confirm, reset_password_validate_token
1+
""" URL Configuration for core auth """
2+
from django.conf.urls import url
3+
4+
from django_rest_passwordreset.views import ResetPasswordValidateTokenViewSet, ResetPasswordConfirmViewSet, \
5+
ResetPasswordRequestTokenViewSet, reset_password_validate_token, reset_password_confirm, \
6+
reset_password_request_token
57

68
app_name = 'password_reset'
79

10+
11+
def add_reset_password_urls_to_router(router, base_path=''):
12+
router.register(
13+
base_path + r'/validate_token',
14+
ResetPasswordValidateTokenViewSet,
15+
basename='reset-password-validate'
16+
)
17+
router.register(
18+
base_path + r'/confirm',
19+
ResetPasswordConfirmViewSet,
20+
basename='reset-password-confirm'
21+
)
22+
router.register(
23+
base_path + r'',
24+
ResetPasswordRequestTokenViewSet,
25+
basename='reset-password-request'
26+
)
27+
28+
829
urlpatterns = [
930
url(r'^validate_token/', reset_password_validate_token, name="reset-password-validate"),
1031
url(r'^confirm/', reset_password_confirm, name="reset-password-confirm"),

django_rest_passwordreset/views.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
from datetime import timedelta
2+
3+
from django.conf import settings
24
from django.contrib.auth import get_user_model
3-
from django.core.exceptions import ValidationError
45
from django.contrib.auth.password_validation import validate_password, get_password_validators
5-
from django.utils.translation import gettext_lazy as _
6+
from django.core.exceptions import ValidationError
67
from django.utils import timezone
7-
from django.conf import settings
8-
from rest_framework import status, exceptions
8+
from django.utils.translation import gettext_lazy as _
9+
from rest_framework import exceptions
910
from rest_framework.generics import GenericAPIView
1011
from rest_framework.response import Response
12+
from rest_framework.viewsets import GenericViewSet
1113

12-
from django_rest_passwordreset.serializers import EmailSerializer, PasswordTokenSerializer, ResetTokenSerializer
1314
from django_rest_passwordreset.models import ResetPasswordToken, clear_expired, get_password_reset_token_expiry_time, \
1415
get_password_reset_lookup_field
16+
from django_rest_passwordreset.serializers import EmailSerializer, PasswordTokenSerializer, ResetTokenSerializer
1517
from django_rest_passwordreset.signals import reset_password_token_created, pre_password_reset, post_password_reset
1618

1719
User = get_user_model()
@@ -22,7 +24,10 @@
2224
'ResetPasswordRequestToken',
2325
'reset_password_validate_token',
2426
'reset_password_confirm',
25-
'reset_password_request_token'
27+
'reset_password_request_token',
28+
'ResetPasswordValidateTokenViewSet',
29+
'ResetPasswordConfirmViewSet',
30+
'ResetPasswordRequestTokenViewSet'
2631
]
2732

2833
HTTP_USER_AGENT_HEADER = getattr(settings, 'DJANGO_REST_PASSWORDRESET_HTTP_USER_AGENT_HEADER', 'HTTP_USER_AGENT')
@@ -156,6 +161,35 @@ def post(self, request, *args, **kwargs):
156161
return Response({'status': 'OK'})
157162

158163

164+
class ResetPasswordValidateTokenViewSet(ResetPasswordValidateToken, GenericViewSet):
165+
"""
166+
An Api ViewSet which provides a method to verify that a token is valid
167+
"""
168+
169+
def create(self, request, *args, **kwargs):
170+
return super(ResetPasswordValidateTokenViewSet, self).post(request, *args, **kwargs)
171+
172+
173+
class ResetPasswordConfirmViewSet(ResetPasswordConfirm, GenericViewSet):
174+
"""
175+
An Api ViewSet which provides a method to reset a password based on a unique token
176+
"""
177+
178+
def create(self, request, *args, **kwargs):
179+
return super(ResetPasswordConfirmViewSet, self).post(request, *args, **kwargs)
180+
181+
182+
class ResetPasswordRequestTokenViewSet(ResetPasswordRequestToken, GenericViewSet):
183+
"""
184+
An Api ViewSet which provides a method to request a password reset token based on an e-mail address
185+
186+
Sends a signal reset_password_token_created when a reset token was created
187+
"""
188+
189+
def create(self, request, *args, **kwargs):
190+
return super(ResetPasswordRequestTokenViewSet, self).post(request, *args, **kwargs)
191+
192+
159193
reset_password_validate_token = ResetPasswordValidateToken.as_view()
160194
reset_password_confirm = ResetPasswordConfirm.as_view()
161195
reset_password_request_token = ResetPasswordRequestToken.as_view()

0 commit comments

Comments
 (0)