Giter Site home page Giter Site logo

anexia-it / django-rest-passwordreset Goto Github PK

View Code? Open in Web Editor NEW
413.0 9.0 144.0 335 KB

An extension of django rest framework, providing a configurable password reset strategy

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%
django django-rest-framework password-reset hacktoberfest

django-rest-passwordreset's People

Contributors

adshin21 avatar anindyamanna avatar anx-abruckner avatar anx-bhagmann avatar anx-cbenke avatar anx-ckreuzberger avatar anx-mfischer avatar beachmachine avatar cal5k avatar christiankreuzberger avatar citixensas avatar daspecster avatar hall-erik avatar harrylafranc avatar hymanzhan avatar iagocanalejas avatar isantosd avatar jmromeroe avatar jonahgeorge avatar justinwingchunghui avatar marianoeramirez avatar mikelandzelo173 avatar nezhar avatar nittolese avatar peletiah avatar rennerocha avatar stan-sack avatar talbenbasat avatar wencakisa avatar yhoiseth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-rest-passwordreset's Issues

How to customize exceptions

Hi,
sorry about my question but I can not find any info about it (title) in docs. How can I extend exceptions e.g
api/password_reset/ - email not found (customize structure)
api/password_reset/confirm - invalid token (customize structure)
...
It is possible to do this? Should I use exception handler?

Changing 'sender' in signal to be object instead of class

Hello,

Thanks for your work on this module!

Would it be possible to pass the actual view object as the sender of the signal handlers, rather than simply the class of the view?

Using DjangoRESTFramework, I've encountered a situation where I need to generate an email containing a link to a password reset form that is in a React app hosted alongside my DRF API. There is no request context for me to determine the domain, since the signal 'sender' is only the class, and not the actual object that generated the signal. There is also a design consideration that prevents me from simply hard-coding the domain value in the application settings.

If the signal sender passed was the actual instance(view) that generated the signal, then I could use the .request attribute of the view.

I think this would be a small/easy/backward compatible change.

Thanks for your consideration,

Joel

Enhancement: Use DRF Serializers and ViewSets instead of APIView

The REST endpoints should be

  • browsable via the DRF browsable API
  • return proper http status codes (e.g., 40x, and not 500)

There are two related issues to this:

I believe that we can tackle both issues by re-writing the package to use DRF Serializers and ViewSets.

I'm closing the other issues and leaving this one open.

Stuck in migrate command

Hi, I try to install de extension and configurate, but when pass through migrations, the first one runs without problems but the command get stuck in the second. Has been running for 1 hour without result.

Variant of ResetPasswordConfirm that validates a token

Idea for an enhancement: it would be great to have an endpoint where a token could be checked for validity, without submitting a new password.

This would fit into the SPA architecture by allowing the app to present an error page instead of a password-reset form if the page is loaded with an invalid token. Otherwise the user has to try submitting the password change request before getting a rejection.

This might be done with an additional param on ResetPasswordConfirm, or a separate view altogether.

Setting min_length and max_length does not work

I have set this inside my settings file, but it does not seem to work at all.

DJANGO_REST_PASSWORDRESET_TOKEN_CONFIG = {
"CLASS": "django_rest_passwordreset.tokens.RandomStringTokenGenerator",
"OPTIONS": {
"min_number": 10,
"max_number": 100
}
}

Django 3.0 is not compatible with extension

celery | File "/usr/local/lib/python3.8/site-packages/django_rest_passwordreset/models.py", line 3, in
celery | from django.utils.encoding import python_2_unicode_compatible
celery | ImportError: cannot import name 'python_2_unicode_compatible' from 'django.utils.encoding' (/usr/local/lib/python3.8/site-packages/django/utils/encoding.py)

MySQL - Incorrect table definition

Hi, there is an issue regarding the migration of django_rest_passwordreset.0002_pk_migration,

Here is the stacktrace:
Traceback (most recent call last):
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/django/db/backends/mysql/base.py", line 101, in execute
return self.cursor.execute(query, args)
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/MySQLdb/cursors.py", line 250, in execute
self.errorhandler(self, exc, value)
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
raise errorvalue
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/MySQLdb/cursors.py", line 247, in execute
res = self._query(query)
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/MySQLdb/cursors.py", line 411, in _query
rowcount = self._do_query(q)
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/MySQLdb/cursors.py", line 374, in _do_query
db.query(q)
File ".local/share/virtualenvs/BTM_KYC-GCftzs5x/lib/python3.5/site-packages/MySQLdb/connections.py", line 278, in query
_mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1075, 'Incorrect table definition; there can be only one auto column and it must be defined as a key')

This SQL query is causing this.
b'ALTER TABLE django_rest_passwordreset_resetpasswordtoken MODIFY id integer AUTO_INCREMENTNULL'

Error:
_mysql_exceptions.OperationalError: (1075, 'Incorrect table definition; there can be only one auto column and it must be defined as a key')

I have printed the query to know which one is causing this issue.

I don't know if this is just in my machine but kindly look into this.

Thanks.

How do I trigger the email signal?

How do I trigger the email signals?
The api is able to verify the email but the signals are not being triggered.
How do I trigger the signals?

Code missing import command

from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives

must be added to the signals snippet

Basic usage questions... maybe a request for the docs?

Please forgive the newbie questions, but I'm trying to understand how this library is supposed to be used. I see that a call to the reset_password endpoint will generate a token and a signal, enabling a function to send an email to the given email address with that token in it. I presume that when the user clicks the link in the email, they can then be presented with a form to fill in a new password. What I don't get is:

  • What endpoint should be in that initial email? The example in the documentation uses reverse('password_reset:reset-password-request'). But wouldn't that just be a circular loop, since that's the endpoint that generated the email in the first place?

  • How can links access the endpoints in this library as POSTs, as they require? At least in plain text emails, when clicked these only seem to show up as GETs.

  • Perhaps somebody can explain the basic data flow for how these endpoints should be used? What is provided, what must be written?

Thanks!

Migration Error at /api/password_reset/

Migration Error at /api/password_rest/
id
Django version = 2.0.6
Python = 3.6
django rest framework = 3.8.2

The error occurs after submitting the post request with email. I am using djongo library. MongoDB as database. Is it the problem with database or version dependencies

Update pipy package

This is more a request than a bug report (sorry but I could not find a better place for it).

This looks like a great little library which will save me from having to repeat this code in my own projects, but Its been a while since the last pipy update and 0.9.7 has quite a few major issues that have now sorted out ... would it be possible to update the pipy version to one of the newest commits soon?

REMOTE_ADDR not set (nginx, gunicorn and unix socket)

The REMOTE_ADDR value is used to set the ip_address of a new instance of ResetPasswordToken class. Unfortunately, as state in this gunicorn issue, "... an unix socket has no remote address any more to comply with the CGI/WSGI spec.".

As a consequence, the persistence of the ResetPasswordToken throws an NotNullViolation exception, because ip_address is empty.

I see that you have introduced the DJANGO_REST_PASSWORDRESET_REMOTE_ADDR variable in the code, but as far as I could understand, this does not solve the problem because its hard coded value (set in the settings.py) will be used as the default value when REMOTE_ADDR does not exists in request.META.

So I'm wondering if it would be a good idea to allow developer to specify the variable (s)he wants to grab from request.META in order to fill ip_address variable.

cannot import name 'message_from_file'

When I try adding 'django_rest_passwordreset' to django apps, I get this error:

Traceback (most recent call last):
  File "manage.py", line 28, in <module>
    from django.core.management import execute_from_command_line
  File "/home/giovanni/git/ozzy-backend/venv/lib/python3.6/site-packages/django/__init__.py", line 1, in <module>
    from django.utils.version import get_version
  File "/home/giovanni/git/ozzy-backend/venv/lib/python3.6/site-packages/django/utils/version.py", line 6, in <module>
    from distutils.version import LooseVersion
  File "/home/giovanni/git/ozzy-backend/venv/lib/python3.6/distutils/__init__.py", line 25, in <module>
    from distutils import dist, sysconfig
  File "/usr/lib64/python3.6/distutils/dist.py", line 10, in <module>
    from email import message_from_file
ImportError: cannot import name 'message_from_file'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 34, in <module>
    ) from exc
ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?

And removing it my app runs fine. Can you help me with this issue?
This has something to do with the email package?

Django: 2.1.2
Python: 3.6
Using virtualenv.

Django IntegrityError: Column 'is_superuser' cannot be null

Using Django 2.1.5 here and this library's 1.0.0a3 version, when sending token and password from a user with no admin privileges ('is_superuser' = False) to the endpoint, I get this error on line 74 on the views.py file
reset_password_token.user.save()

It is because Django, in my specific case, when returning user from the DB and a BooleanField is False it returns with 'null' as value (i really don't understand how or why).

A quick hack to solve this is to put an ugly if else to check if user.is_superuser, user.is_staff are null, if they are, then assign False to them:
if reset_password_token.user.is_superuser is None:
reset_password_token.user.is_superuser = False
if reset_password_token.user.is_staff is None:
reset_password_token.user.is_staff = False

Can someone give me other options or explain me how is it that django query gives me null instead of False

authentication_classes = () in password validate/confirm endpoints?

I found that if the user has an (invalid) local Bearer: <hex> cookie that gets sent as a header, the three views can fail authentication and return a 401. Is this intentional? Shouldn't these views have authentication_classes = () so they work even if there's a leftover token in the browser?

There might be a security-related reason for it to be this way but I'm not sure I can think what it is.

Historic of requested password resets

Hi, after some thinking of the use i personally do of this library i think allowing ResetPasswordToken soft-deletion (maybe in some configuration param) could be a nice addition to the library current features.

Allowing this you can use ip_address (already being saved) to detect account attacks (as an example). But at less you can have a historic of user reset requests.

Extra _ in code snippet

_("Password Reset for {title}".format(title="Some website title")),

Extra _ has been added. [Typo]

after submitting the email; relation "django_rest_passwordreset_resetpasswordtoken" does not exist

Hi all,
I'm testing this locally, and when I submit the email, it gives me an error. this is the output:

Internal Server Error: /api/password_reset/

Traceback (most recent call last):
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "django_rest_passwordreset_resetpasswordtoken" does not exist
LINE 1: DELETE FROM "django_rest_passwordreset_resetpasswordtoken" W...
                    ^


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/rest_framework/views.py", line 489, in dispatch
    response = self.handle_exception(exc)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/rest_framework/views.py", line 449, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/rest_framework/views.py", line 486, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django_rest_passwordreset/views.py", line 105, in post
    clear_expired(now_minus_expiry_time)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django_rest_passwordreset/models.py", line 94, in clear_expired
    ResetPasswordToken.objects.filter(created_at__lte=expiry_time).delete()
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/models/query.py", line 617, in delete
    deleted, _rows_count = collector.delete()
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/models/deletion.py", line 284, in delete
    count = qs._raw_delete(using=self.using)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/models/query.py", line 631, in _raw_delete
    return sql.DeleteQuery(self.model).delete_qs(self, using)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/models/sql/subqueries.py", line 80, in delete_qs
    cursor = self.get_compiler(using).execute_sql(CURSOR)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 894, in execute_sql
    raise original_exception
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 884, in execute_sql
    cursor.execute(sql, params)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py", line 164, in execute
    return self._record(self.cursor.execute, sql, params)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py", line 106, in _record
    return method(sql, params)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/noora/cartwheel_env/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "django_rest_passwordreset_resetpasswordtoken" does not exist
LINE 1: DELETE FROM "django_rest_passwordreset_resetpasswordtoken" W...
                    ^

[31/Jul/2019 14:01:19] "POST /api/password_reset/ HTTP/1.1" 500 200689

can you help me PLZ

Unable to access verify_token and confirm endpoints

Hello,

I am probably doing something silly wrong, but I've been unable to use the /reset_password/confirm/ and /reset_password/validate_token/ endpoints.

I am able to post to /reset_password/, generate the token, receive the signal and send the email.

path('api/password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset')),

I have the above in my urls.py

When I go to: http://127.0.0.1:8000/api/password_reset/reset_password/
I can post an email to request a token.

When I go to: http://127.0.0.1:8000/api/password_reset/reset_password/validate_token/ or http://127.0.0.1:8000/api/password_reset/reset_password/confirm/ there is no change from http://127.0.0.1:8000/api/password_reset/reset_password/, this is what I see:

image

Any idea why this is the case?

Thanks!

Return 400 instead of 500/404?

Any reason why the app return 500/404 error instead of 400 in these, and perhaps other, cases?

  • non-existent email address has been provided
  • token is invalid (expired, deleted, mistyped)

I think that catching 400 and getting the errors from the response would be much neater to work with in FE?

Wrong field lookup in views

Hi, thanks for this plugin! It looks like it'll save at least few hours of unnecessary work!

I just have installed the plugin and started getting internal server error from views.py. The issue is the line 102:

users = User.objects.filter(email__iexact=email)

In an app that I'm currently working on, there's no email field, but it's actually a username field that stores the email.

How about updating the plugin, so that it allows to parametrize the name of the field used throughout the data flow? This parameter could be use in views.py, but also in serializers.py (so there are no inconsistencies in parameter between them) and elsewhere.

Thanks!

Mongo integration.

Hi,
i use mongodb with django and when i use your lib, i got this error:


Internal Server Error: /api/auth/reset-password/verify-token/
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/djongo/sql2mongo/query.py", line 287, in _align_results
    ret.append(doc[selected.column])
KeyError: 'id'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/macos/PycharmProjects/Challenges/venv/lib/python3.7/site-packages/rest_framework/views.py", line 494, in dispatch
    response = self.handle_exception(exc)
  File "/Users/macos/PycharmProjects/Challenges/venv/lib/python3.7/site-packages/rest_framework/views.py", line 454, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/macos/PycharmProjects/Challenges/venv/lib/python3.7/site-packages/rest_framework/views.py", line 491, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/macos/PycharmProjects/Challenges/authentification/views.py", line 74, in post
    reset_password_token = ResetPasswordToken.objects.filter(key=token).first()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/query.py", line 653, in first
    for obj in (self if self.ordered else self.order_by('pk'))[:1]:
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/query.py", line 274, in __iter__
    self._fetch_all()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/query.py", line 55, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1133, in execute_sql
    return list(result)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1512, in cursor_iter
    for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1512, in <lambda>
    for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/utils.py", line 96, in inner
    return func(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/djongo/cursor.py", line 59, in fetchmany
    ret.append(self.result.next())
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/djongo/sql2mongo/query.py", line 767, in __next__
    return next(self._result_generator)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/djongo/sql2mongo/query.py", line 773, in __iter__
    yield from iter(self._query)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/djongo/sql2mongo/query.py", line 180, in __iter__
    yield self._align_results(doc)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/djongo/sql2mongo/query.py", line 290, in _align_results
    raise MigrationError(selected.column)
djongo.sql2mongo.MigrationError: id

it seems there is a problem with mongoDB integration, i dont have the id row, so the model is not implemented well

Response should be configurable.

When I used these API end points i need to request them in backend and behalf of that i need to make new response then return to the frontend. That increase my code as well as time to request two API only for configure response (response message is not configurable).

When testing in django receiving KeyError: 'HTTP_USER_AGENT'

Hi,

When testing and posting to the api without HTTP_USER_AGENT or REMOTE_ADDR, There's a server error and KeyError.

The problem lays here:

token = ResetPasswordToken.objects.create(
                        user=user,
                        user_agent=request.META['HTTP_USER_AGENT'],
                        ip_address=request.META['REMOTE_ADDR']
                    )

django_rest_passwordreset/views.py line 136

The fix is to use get with default.

p.s.
Thanks for the library

Cannot access the browsable API for the given end-points

I see in the docs some screenshots of the browsable API, however when i try to access it, I get the following message:

Method \"GET\" not allowed

Also, in the generated docs, where it says Interact there is no form to interact with.

Where these removed?

DRF browsable API is not working

When I go to reset-password endpoint DRF browsable API is not working (package doc mentioned that browsable API support is available).

urlpatterns = [
    path('password-reset/', include('django_rest_passwordreset.urls', namespace='password_reset')),
]

Is there any settings that I have to change?

unable to enter into function password_reset_token_created function by generating signal

from django.dispatch import receiver
from django.template.loader import render_to_string
from django.urls import reverse
from django_rest_passwordreset.signals import reset_password_token_created, pre_password_reset,
post_password_reset

from sixwallz_app import config
from sixwallz_app.send_invitaion_mail import *
import logging

log = logging.getLogger(name)

@receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):
"""
Handles password reset tokens
When a token is created, an e-mail needs to be sent to the user
:param sender: View Class that sent the signal
:param instance: View Instance that sent the signal
:param reset_password_token: Token Model Object
:param args:
:param kwargs:
:return:
"""
print("Write Something")
# send an e-mail to the user
context = {
'current_user': reset_password_token.user,
'username': reset_password_token.user.username,
'email': reset_password_token.user.email,
'reset_password_url': "{}?token={}".format(reverse('password_reset:reset-password-request'),
reset_password_token.key)
}

CVE-2019-19844 potentials

Hi,

After CVE-2019-19844 was announced I had a look through our internal Django project and dependencies to check it wasn't affected and wanted to make sure there weren't any attack angles.

Here is the potential misbehaving line in this project

users = User.objects.filter(**{'{}__iexact'.format(get_password_reset_lookup_field()): email})
- a database search with __iexact which can match with a different address under the conditions in the CVE.

It seems to be mitigated by

as the destination email is fetched from the DB and so the token is sent to the attacked user's actual email address.

To completely resolve the issues described in the CVE you'll need to do a _unicode_ci_compare after the data is returned from the DB to filter out the users that shouldn't have been matched by __iexact.

Let me know if you want me to try to write a patch for this.

ValidationError causes 500 error, not DRF-style 400

The ValidationError raised by ResetPasswordConfirm and ResetPasswordRequestToken should be the DRF version, not the django.core.exceptions version.

from django.core.exceptions import ValidationError

should be

from rest_framework.exceptions import ValidationError

Otherwise it crashes with a 500 instead of returning an enriched 400.

/password_reset should return 200 if no users have the given email

The library currently returns a 400 if the email passed in POST /password_reset isn't found in the DB. This is bad because a bad actor can query this endpoint to discover whether or not email addresses are registered with the service.

For example, this would not be suitable for a dating site, where somebody's partner may use this exploit to discover whether or not they have an account.

I think that a 200 should be returned either way, or the response code should be configurable.

If you agree I can make a PR for the change.

Instead of deleting expired tokens: allow to reenable them

It would be pretty nice to offer the possibility to re-enable deactivated tokens instead of deleting them.

My use case:
Initially all my users are going to get random passwords, so they cannot log in. I do this because I have to change some data on their accounts, even if they do not use their account.
But I would like to give them the "password change token" as a "registration token", printed on a card.
The users are asked to login and set (in fact change) their password within 24 hours, but I expect that some will not manage to change it in the given time.

Instead of printing a new activation token, it would be nice to just "re-enable" the old one for another 24 hours.

Is this something which is a lot of work? I am relatively new to Django so I fear I cannot do it myself, but I would be glad to be of any help you need.

django.db.utils.ProgrammingError: Multiple primary keys for table «django_rest_passwordreset_resetpasswordtoken» are not allowed.

Hi, after updating from version 0.9.4 to 0.9.5 i am getting a django.db.utils.ProgrammingError: Multiple primary keys for table «django_rest_passwordreset_resetpasswordtoken» are not allowed. trying to do a manage.py migrate.

I don't really know what information you would need to track this issue but i would love to collaborate with you to fix this issue so feel free to ask for whatever context information you would need.

  File "manage.py", line 31, in <module>
    execute_from_command_line(sys.argv)
  File "\venv\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line

    utility.execute()
  File "\venv\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "\venv\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "\venv\lib\site-packages\django\core\management\base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "\venv\lib\site-packages\django\core\management\base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "\venv\lib\site-packages\django\core\management\commands\migrate.py", line 203, in handle
    fake_initial=fake_initial,
  File "\venv\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "\venv\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "\venv\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "\venv\lib\site-packages\django\db\migrations\migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "\venv\lib\site-packages\django\db\migrations\operations\fields.py", line 216, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "\venv\lib\site-packages\django\db\backends\base\schema.py", line 523, in alter_field
    old_db_params, new_db_params, strict)
  File "\venv\lib\site-packages\django\db\backends\postgresql\schema.py", line 122, in _alter_field
    new_db_params, strict,
  File "\venv\lib\site-packages\django\db\backends\base\schema.py", line 719, in _alter_field
    "columns": self.quote_name(new_field.column),
  File "\venv\lib\site-packages\django\db\backends\base\schema.py", line 133, in execute
    cursor.execute(sql, params)
  File "\venv\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "\venv\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "\venv\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "\venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "\venv\lib\site-packages\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "\venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: Multiple primary keys for table «django_rest_passwordreset_resetpasswordtoken» are not allowed.

Information leakage in admin panel

Same as with Issue 6131 on django-rest-frameworks (regarding Token Authentication), this package uses the password reset token as the primary key.

An administrator clicking on a token within the admin panel will leak that token into one or many logfiles.
E.g.:

  • access log of the webserver used
  • any proxy that logs
  • webbrowser history
  • any django log, depending on your django.requests or middleware logging

random numbers instead of token

Hello sir,
I am very impressed with this module and decided to use it. I would like to override the functionality where i can change the key
def generate_key():
""" generates a pseudo random code using os.urandom and binascii.hexlify """
return binascii.hexlify(os.urandom(32)).decode()

to randint.
Please let me know if there is a way to override it?

ImportError: No module named django_rest_passwordreset

Hello lovely day,

I am working on a very old codebase with django 1.8 and python 2.7 on a venv. I am using version 0.9.7 which should be compatible, am I missing something? was django1.8 support dropped for this package?

ImportError: No module named django_rest_passwordreset

Here's part of my pip2 freeze
django-rest-passwordreset==0.9.7 django-sendfile==0.3.10 django-taggit==0.22.1 django-test-without-migrations==0.6 django-treebeard==4.2.0 djangorestframework==3.6.0 djangorestframework-recursive==0.1.1

How can i post email id for password reset ?

When I am putting this urls into my browser:-

  from django.conf.urls import url, include
   urlpatterns = [
    ...
     url(r'^api/password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset')),
   ...
  ]

then I am getting "Method "GET" not allowed." there is nothing to show where i put email.

Email not sent

I am able to configure django-rest-passwordreset successfully and I receive the response:
{
"status": "OK"
}
However, i am not receiving in the email though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.