Skip to content

Commit

Permalink
Allow nullable/blank fields, fix header values and add docu about tho…
Browse files Browse the repository at this point in the history
…se values
  • Loading branch information
anx-ckreuzberger committed Aug 2, 2019
1 parent 96e2341 commit 9c64ea6
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 22 deletions.
56 changes: 41 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,6 @@ The following endpoints are provided:

where `${API_URL}/` is the url specified in your *urls.py* (e.g., `api/password_reset/`)


### Configuration / Settings

The following settings can be set in Djangos ``settings.py`` file:

* `DJANGO_REST_MULTITOKENAUTH_RESET_TOKEN_EXPIRY_TIME` - time in hours about how long the token is active (Default: 24)

**Please note**: expired tokens are automatically cleared based on this setting in every call of ``ResetPasswordRequestToken.post``.

* `DJANGO_REST_PASSWORDRESET_NO_INFORMATION_LEAKAGE` - will cause a 200 to be returned on `POST ${API_URL}/reset_password/`
even if the user doesn't exist in the databse (Default: False)

* `DJANGO_REST_MULTITOKENAUTH_REQUIRE_USABLE_PASSWORD` - allows password reset for a user that does not
[have a usable password](https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.has_usable_password) (Default: True)

### Signals

* ``reset_password_token_created(sender, instance, reset_password_token)`` Fired when a reset password token is generated
Expand Down Expand Up @@ -140,6 +125,21 @@ def password_reset_token_created(sender, instance, reset_password_token, *args,
If you want to test this locally, I recommend using some kind of fake mailserver (such as maildump).



# Configuration / Settings

The following settings can be set in Djangos ``settings.py`` file:

* `DJANGO_REST_MULTITOKENAUTH_RESET_TOKEN_EXPIRY_TIME` - time in hours about how long the token is active (Default: 24)

**Please note**: expired tokens are automatically cleared based on this setting in every call of ``ResetPasswordRequestToken.post``.

* `DJANGO_REST_PASSWORDRESET_NO_INFORMATION_LEAKAGE` - will cause a 200 to be returned on `POST ${API_URL}/reset_password/`
even if the user doesn't exist in the databse (Default: False)

* `DJANGO_REST_MULTITOKENAUTH_REQUIRE_USABLE_PASSWORD` - allows password reset for a user that does not
[have a usable password](https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.has_usable_password) (Default: True)

## Custom Email Lookup

By default, `email` lookup is used to find the user instance. You can change that by adding
Expand All @@ -148,6 +148,19 @@ DJANGO_REST_LOOKUP_FIELD = 'custom_email_field'
```
into Django settings.py file.

## Custom Remote IP Address and User Agent Header Lookup

If your setup demands that the IP adress of the user is in another header (e.g., 'X-Forwarded-For'), you can configure that (using Django Request Headers):

```python
DJANGO_REST_PASSWORDRESET_IP_ADDRESS_HEADER = 'HTTP_X_FORWARDED_FOR'
```

The same is true for the user agent:

```python
HTTP_USER_AGENT_HEADER = 'HTTP_USER_AGENT'
```

## Custom Token Generator

Expand Down Expand Up @@ -249,6 +262,7 @@ django-rest-passwordreset Version | Django Versions | Django Rest Framework Vers
--------------------------------- | ----------------| ------------------------------
0.9.7 | 1.8, 1.11, 2.0, 2.1 | 3.6 - 3.9
1.0 | 1.11, 2.0, 2.2 | 3.6 - 3.9
1.1 | 1.11, 2.2 | 3.6 - 3.9

## Documentation / Browsable API

Expand Down Expand Up @@ -307,6 +321,18 @@ You need to make sure that the code with `@receiver(reset_password_token_created
default_app_config = 'your_django_project.some_app.SomeAppConfig'
```

### MongoDB not working

Apparently, the following piece of code in the Django Model prevents MongodB from working:

```python
id = models.AutoField(
primary_key=True
)
```

See issue #49 for details.

## Contributions

This library tries to follow the unix philosophy of "do one thing and do it well" (which is providing a basic password reset endpoint for Django Rest Framework). Contributions are welcome in the form of pull requests and issues! If you create a pull request, please make sure that you are not introducing breaking changes.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-08-02 12:39
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('django_rest_passwordreset', '0002_pk_migration'),
]

operations = [
migrations.AlterField(
model_name='resetpasswordtoken',
name='ip_address',
field=models.GenericIPAddressField(blank=True, default='', null=True, verbose_name='The IP address of this session'),
),
migrations.AlterField(
model_name='resetpasswordtoken',
name='user_agent',
field=models.CharField(blank=True, default='', max_length=256, verbose_name='HTTP User Agent'),
),
]
7 changes: 5 additions & 2 deletions django_rest_passwordreset/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ def generate_key():

ip_address = models.GenericIPAddressField(
_("The IP address of this session"),
default="127.0.0.1"
default="",
blank=True,
null=True,
)
user_agent = models.CharField(
max_length=256,
verbose_name=_("HTTP User Agent"),
default=""
default="",
blank=True,
)

def save(self, *args, **kwargs):
Expand Down
9 changes: 5 additions & 4 deletions django_rest_passwordreset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
'reset_password_request_token'
]

HTTP_USER_AGENT_HEADER = getattr(settings, 'DJANGO_REST_PASSWORDRESET_HTTP_USER_AGENT_HEADER', 'HTTP_USER_AGENT')
HTTP_IP_ADDRESS_HEADER = getattr(settings, 'DJANGO_REST_PASSWORDRESET_IP_ADDRESS_HEADER', 'REMOTE_ADDR')


class ResetPasswordConfirm(GenericAPIView):
"""
Expand Down Expand Up @@ -140,10 +143,8 @@ def post(self, request, *args, **kwargs):
# no token exists, generate a new token
token = ResetPasswordToken.objects.create(
user=user,
user_agent=request.META.get('HTTP_USER_AGENT',
getattr(settings, 'DJANGO_REST_PASSWORDRESET_HTTP_USER_AGENT', '')),
ip_address=request.META.get('REMOTE_ADDR',
getattr(settings, 'DJANGO_REST_PASSWORDRESET_REMOTE_ADDR', ''))
user_agent=request.META.get(HTTP_USER_AGENT_HEADER, ''),
ip_address=request.META.get(HTTP_IP_ADDRESS_HEADER, ''),
)
# send a signal that the password token was created
# let whoever receives this signal handle sending the email for the password reset
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name='django-rest-passwordreset',
version='1.1.0rc2',
version='1.1.0rc3',
packages=find_packages(),
include_package_data=True,
license='BSD License',
Expand Down

0 comments on commit 9c64ea6

Please sign in to comment.