Django reset password not catching invalid email ids - python

I'm using Django's built in reset password views with custom templates. Although it works successfully, it does not show an error message if the email id submitted is not already registered in the site.
I followed the instructions here to help me reach till this point.
#urls.py
url(r'^users/password/reset/$',
'django.contrib.auth.views.password_reset',
{'post_reset_redirect' : '/users/password/reset/done/'},
name="reset_password"
),
url(r'^users/password/reset/done/$',
'django.contrib.auth.views.password_reset_done'
),
url(r'^users/password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
'django.contrib.auth.views.password_reset_confirm',
{'post_reset_redirect' : '/users/password/done/'}
),
url(r'^users/password/done/$',
'django.contrib.auth.views.password_reset_complete'
),
Whatever email id I give, Django always redirects me to /users/password/reset/done/ which says:
We've e-mailed you instructions for setting your password to the e-mail address
you submitted.
You should be receiving it shortly.
This is misleading, since users might've entered their email address wrong and still be seeing the above page.
How do I show an error message if the email address is not registered?
Thanks in advance.

The easy way to implement that is to use django-allauth. Works without any extra setting, leaving the message: The e-mail address is not assigned to any user account.
I have not worked with raw users in a while, but if you absolutely need that you could try to create your own view and verify manually that the email is in the server (if it is you can call the original function). You may need to extend the template or the form to redirect the action to your own view.

Related

Page not found http://127.0.0.1:8000/manageAccount/a/delete

I don't know why I get this page because I think all works right. I couldn't identify why the browser gives this error but below url is not worked because user object not get because its redirect on login page but i am going on this url http://127.0.0.1:8000/user_homeview/a/delete its work successfully but user_homeview that template is after login show means homepage i dont know what can i do please tell me:
Page not found http://127.0.0.1:8000/manageAccount/a/delete
Here is my code:
template.html:
Delete Account<Br>
urls.py:
path('<str:username>/delete', delete_user, name='delete-user')
views.py:
def delete_user(request, username):
context = {}
u = User.objects.filter(username=username)
u.delete()
messages.success(request,'your account delete')
return render(request, 'home/login.html', context=context)
Check on your developer tools what is being rendered on your href attribute. I think the url is not being rendered correctly by your current template tag. It should be like this, according to Django's documentation:
Delete Account<Br>
Note that you don't have access to request by default in your templates. If you are deleting a user by its username, the previous code would be:
Delete Account<Br>
as user is accessible by default in your templates.
Be aware that this is not the secure way of deleting users, as anyone with other user's information can access this link to delete accounts. You should use POST requests and check if the user requesting the delete link is the owner of the account.

Django: phone verification for inactive account

I'd like to implement phone verification with pyotp in my view class-based Django (2.5) project.
After new users sign up (specifying name, phone, e-mail and password) in RegisterView, they should be redirected to GetAccessCodeView with an input field for verification code and a hidden field with a secure token. For generating and sending the code and the token I have to pass there a newly created user instanse from RegisterView to GetAccessCodeView.
How can I do that? Currently newly created users have is_active field set to False (it should become True after code succesful verification), thus cannot be authorized by default, so without changing login procedure, it is impossible to use request.user directly. But if I let inactive users to log in, then all the login_required views will let unconfirmed users to open corresponding pages. Should I write is_active check for each view manually or maybe Django has some ready stuff like 'login_and_active_required'? Or maybe there is some different solution?

Implement Forgot Password/Email Verification django rest with ReactJS

I want to implement forgot password or email verification with django and react,
To implement forgot password I used django rest auth.Here below urls are:
url(
r'^rest-auth/password/reset/$',
PasswordResetView.as_view(),
name='password_reset',
),
url(
r'^rest-auth/password/reset/confirm/'
r'(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
I have successfully hit the request to first url from my react js front end,and I also received the email with token and uid, but the link redirects me to django rest native UI however I want to be in react framework UI.
So how can I implement this? is there any suitable way to implement forgot password with react and django as it is not done by django rest auth because the flow of react front end disturbs.
So in order to obtain a token from verification link you could use a lib like query-string. Basically you pass location and go on from there, documentation is pretty reach so you should have no problem.

flask-user registration: add one more mail id

I am using flask-user package for user registration. Once the user clicks on register, by default it will send an email to the users' email. I want to add admin email along with that. Is it possible to customize it?
I found this but I am not sure how to proceed with that.
Any help would be great.
After taking help of my colleague, I figured out that this can be done by listening to 'signals' sent by the application. For example:
#user_registered.connect_via(app)
def after_user_registered(sender, user, **kwargs):
msg = Message(subject="A new user registered",
body='Some message',
recipients=["admin#example.com"])
mail.send(msg)
PS: This I wanted to implement so that admin can get an email whenever a new user is registered. Hope this helps someone :)

Django user impersonation by admin

I have a Django app. When logged in as an admin user, I want to be able to pass a secret parameter in the URL and have the whole site behave as if I were another user.
Let's say I have the URL /my-profile/ which shows the currently logged in user's profile. I want to be able to do something like /my-profile/?__user_id=123 and have the underlying view believe that I am actually the user with ID 123 (thus render that user's profile).
Why do I want that?
Simply because it's much easier to reproduce certain bugs that only appear in a single user's account.
My questions:
What would be the easiest way to implement something like this?
Is there any security concern I should have in mind when doing this? Note that I (obviously) only want to have this feature for admin users, and our admin users have full access to the source code, database, etc. anyway, so it's not really a "backdoor"; it just makes it easier to access a user's account.
I don't have enough reputation to edit or reply yet (I think), but I found that although ionaut's solution worked in simple cases, a more robust solution for me was to use a session variable. That way, even AJAX requests are served correctly without modifying the request URL to include a GET impersonation parameter.
class ImpersonateMiddleware(object):
def process_request(self, request):
if request.user.is_superuser and "__impersonate" in request.GET:
request.session['impersonate_id'] = int(request.GET["__impersonate"])
elif "__unimpersonate" in request.GET:
del request.session['impersonate_id']
if request.user.is_superuser and 'impersonate_id' in request.session:
request.user = User.objects.get(id=request.session['impersonate_id'])
Usage:
log in: http://localhost/?__impersonate=[USERID]
log out (back to admin): http://localhost/?__unimpersonate=True
It looks like quite a few other people have had this problem and have written re-usable apps to do this and at least some are listed on the django packages page for user switching. The most active at time of writing appear to be:
django-hijack puts a "hijack" button in the user list in the admin, along with a bit at the top of page for while you've hijacked an account.
impostor means you can login with username "me as other" and your own password
django-impersonate sets up URLs to start impersonating a user, stop, search etc
I solved this with a simple middleware. It also handles redirects (that is, the GET parameter is preserved during a redirect). Here it is:
class ImpersonateMiddleware(object):
def process_request(self, request):
if request.user.is_superuser and "__impersonate" in request.GET:
request.user = models.User.objects.get(id=int(request.GET["__impersonate"]))
def process_response(self, request, response):
if request.user.is_superuser and "__impersonate" in request.GET:
if isinstance(response, http.HttpResponseRedirect):
location = response["Location"]
if "?" in location:
location += "&"
else:
location += "?"
location += "__impersonate=%s" % request.GET["__impersonate"]
response["Location"] = location
return response
#Charles Offenbacher's answer is great for impersonating users who are not being authenticated via tokens. However, it will not work with clients side apps that use token authentication. To get user impersonation to work with apps using tokens, one has to directly set the HTTP_AUTHORIZATION header in the Impersonate Middleware. My answer basically plagiarizes Charles's answer and adds lines for manually setting said header.
class ImpersonateMiddleware(object):
def process_request(self, request):
if request.user.is_superuser and "__impersonate" in request.GET:
request.session['impersonate_id'] = int(request.GET["__impersonate"])
elif "__unimpersonate" in request.GET:
del request.session['impersonate_id']
if request.user.is_superuser and 'impersonate_id' in request.session:
request.user = User.objects.get(id=request.session['impersonate_id'])
# retrieve user's token
token = Token.objects.get(user=request.user)
# manually set authorization header to user's token as it will be set to that of the admin's (assuming the admin has one, of course)
request.META['HTTP_AUTHORIZATION'] = 'Token {0}'.format(token.key)
i don't see how that is a security hole any more than using su - someuser as root on a a unix machine. root or an django-admin with root/admin access to the database can fake anything if he/she wants to. the risk is only in the django-admin account being cracked at which point the cracker could hide tracks by becoming another user and then faking actions as the user.
yes, it may be called a backdoor, but as ibz says, admins have access to the database anyways. being able to make changes to the database in that light is also a backdoor.
Set up so you have two different host names to the same server. If you are doing it locally, you can connect with 127.0.0.1, or localhost, for example. Your browser will see this as three different sites, and you can be logged in with different users. The same works for your site.
So in addition to www.mysite.com you can set up test.mysite.com, and log in with the user there. I often set up sites (with Plone) so I have both www.mysite.com and admin.mysite.com, and only allow access to the admin pages from there, meaning I can log in to the normal site with the username that has the problems.

Categories

Resources