Issue with saving user information using django_registration - django

I am using django_registration v0.8 and using the docs here: http://readthedocs.org/docs/django-registration/en/latest/index.html
I have successfully installed the app, and I am using the default backend for my registration purposes.
I have tested this and I can get the form to show up properly at '/accounts/register'
However, one problem is that if I try and break the form input (different password1 and password2 or improper username), no validation errors are being invoked.
The issue also, is that the username, email, and password data is not being stored in auth_user, and the activation email isn't being sent.
From the default backend doc, "During registration, a new instance of django.contrib.auth.models.User is created to represent the new account, with the is_active field set to False. An email is then sent to the email address of the account, containing a link the user must click to activate the account; at that point the is_active field is set to True, and the user may log in normally."
I believe this new instance of django.contrib.auth.models.User is not being created.
I have also included the necessary email settings:
EMAIL_USE_TLS = True
EMAIL_HOST = "smtp.gmail.com"
EMAIL_HOST_USER = "Email"
EMAIL_HOST_PASSWORD = "Password"
EMAIL_PORT = 587
Any help on getting this straight? I am pretty sure I am missing something simple, but been trying to figure it out without any progress. Any help is greatly appreciated.

Sounds like the form is actually catching the error but you're just not seeing it. Do you have any code in your template that's checking for form errors? Something like the following could help you see if an error has occured:
{% if form.errors %}
<div class="lead">
<h3 class="error">
Please correct the error{{ form.errors|pluralize }} below.
</h3>
</div>
{% endif %}

Related

How to remove change password link from django admin site?

I am using active directory login authentication for my django web application. So there is no need of change password link in admin site.
I have searched lot of article, but I haven't found any thing to hide change password link.
So what is the way of hiding change password link from admin?
You don't need to override admin template.
If user.has_usable_password() returns False, then Django will not display change password URL for that user.
user.has_usable_password()can be made to return False by calling user.set_unusable_password().
From docs:
set_unusable_password()
Marks the user as having no password set. This isn’t the same as having a blank string for a password. check_password() for this user will never return True. Doesn’t save the User object.
You may need this if authentication for your application takes place against an existing external source such as an LDAP directory.
has_usable_password()
Returns False if set_unusable_password() has been called for this user.
Source code for condition filter in Django base admin template:
{% if user.has_usable_password %}
{% translate 'Change password' %}
{% endif %}

Communicate username in activation email

Using Django-Registration-Redux here. The activation email with a link is being send perfectly and I've adjusted the template for the email.
But I'm wondering if someone can give an example code of how to communicate the Username they just created in this email. {{}} and what settings to adjust.
Thank you in advance!
The user variable is available in the context of the activation email template. So to output username just add this code: {{ user.username }}.

Authentication using Email and resulted routing problems

I'm trying to Authenticate users by their emails instead of username.
I'm using django-userena and by using its Docs,etc. I set almost anything that is needed. Something like : USERENA_WITHOUT_USERNAMES = True in its setting, etc.
But after signing up, I've faced a chain of problems. like trying to pass my username in the url for authentication, signup completion problems, etc.
I changed some view functions that need username as an argument, but this method neither solved my problem , nor is a correct (and maybe secure) way to do it.
for instance, by routing to this URL http://127.0.0.1:8000/accounts/signup/complete/ (after $ ./manage.py check_permissions ) I get this error:
global name 'username' is not defined
/userena/views.py in directto_user_template
user = get_object_or_404(User, username_iexact=username)
Is there anything that I'm missing ??
UPDATE:
Here is the output that I get:
Caught NoReverseMatch while rendering: Reverse for 'userena_activate'
with arguments '('xyz#xyz.com',
'70b60d1d97015e03ba8d57f31e4c7ff14d6ab753')' and keyword arguments
'{}' not found.
It's clear that userena tries to the email as username with URL :
userena/templates/userena/emails/activation_email_message.txt, error at line 8
1 {% load i18n %}{% autoescape off %}
2 {% if not without_usernames %}{% blocktrans with user.username as username %}Dear {{ username }},{% endblocktrans %}
3 {% endif %}
4 {% blocktrans with site.name as site %}Thank you for signing up at {{ site }}.{% endblocktrans %}
5
6 {% trans "To activate your account you should click on the link below:" %}
7
8 {{ protocol }}://{{ site.domain }}{% url userena_activate user.username activation_key %}
9
10 {% trans "Thanks for using our site!" %}
11
12 {% trans "Sincerely" %},
13 {{ site.name }}
14 {% endautoescape %}
UPDATE 2:
Alright . by reading the source code for SignupFormOnlyEmail class form, it says that a random username is generated automatically.
class SignupFormOnlyEmail(SignupForm):
"""
Form for creating a new user account but not needing a username.
This form is an adaptation of :class:`SignupForm`. It's used when
``USERENA_WITHOUT_USERNAME`` setting is set to ``True``. And thus the user
is not asked to supply an username, but one is generated for them. The user
can than keep sign in by using their email.
"""
def __init__(self, *args, **kwargs):
super(SignupFormOnlyEmail, self).__init__(*args, **kwargs)
del self.fields['username']
def save(self):
""" Generate a random username before falling back to parent signup form """
while True:
username = sha_constructor(str(random.random())).hexdigest()[:5]
try:
User.objects.get(username__iexact=username)
except User.DoesNotExist: break
self.cleaned_data['username'] = username
return super(SignupFormOnlyEmail, self).save()
UPDATE :
I finally solved the problem. I was also using django-email-as-username beside to django-userena. This was the cause of my problem. Apparently, they have some conflicts. WATCH OUT
You've defined url route userena_activate with keyword arguments (username and activation_key), but you call it just with arguments, change template to keyword arguments:
{% url userena_activate username=user.username activation_key=activation_key %}
edit due to comment:
I'm not sure if I understand your problem corectly, but I think there's a problem elsewhere. Yours error message says:
Caught NoReverseMatch while rendering: Reverse for 'userena_activate' with arguments '('xyz#xyz.com', '70b60d1d97015e03ba8d57f31e4c7ff14d6ab753')' and keyword arguments '{}' not found.
It seems you pass valid arguments to function, but you pass them wrong way. URL route in urls.py is defined in a way to expect kwargs, but you pass just args, which mismatch its definition. That is why you get this error message. Simple pass arguments as kwargs (that means each argument is passed with its name and value as showed above).
urls.py difference between argument and keyword argument:
url(r'^(?P<username>[\.\w]+)/activate/(?P<activation_key>\w+)/$', userena_views.activate, name='userena_activate'),
^ this is _keyword argument_ 'username', expects value with argument value AND name
and
url(r'^page/(.*)/$', userena_views.ProfileListView.as_view(), name='userena_profile_list_paginated'),
^ this is argument, expects only value, not argument name
A really simple alternative for using the email address as the username (effectively) is django-easy-userena - this is an upward compatible fork of Userena that adds a few nice features:
use email address as effective user ID - generates a random numeric
username that is hidden in forms and confirmation emails
fewer dependencies - doesn't require django-guardian or easy-thumbnails
terms of service agreement field is built in, displays as checkbox
I've had good results with this - installation was manual for some reason (copy userena dir to site-packages) but it worked without hassles.
I like the overall Userena approach, but easy-userena is a better fit for what I need.

How to update the password and 'is_staff' status while using django.contrib.auth models

I am developing a web based application in which i need to update the password and is_staff status of a user from Admin(template) page. To do this i created a template which are showing the list of all registered users. see the template:
{% for obj in users_list.object_list %}
<tr class="{% cycle 'odd' 'even' %}">
<td>{{obj}}</td>
<td>{{obj.first_name}}</td>
<td>{{obj.last_name}}</td>
<td>{{obj.email}}</td>
<td>{{obj.is_staff}}</td>
The above code showing the list of all users includes their Full name, Email and is_staff status. What i want, when admin will click on the user name (i uses the href attributes). It will get the option to update the password and is_staff status for a clicked user at open page.
To do this i am not able to find out how to pass the id of user in following line. I tried with user.pk but it always given 1 to me. May be it is returning the current loginned user id but the loginned user is super user also:
<td>{{obj.first_name}}</td>
The reference to the user is obj, not user. So obj.pk should work.

Django password reset. Not sending mail

I'm trying to get the django password reset working but the reset email does not get sent.
I know my email is properly configured because the following works both in the shell and in one of my views (I'm using it to get support email to myself).
from django.core.mail import send_mail
send_mail('Subject here', 'Here is the message.',
'admin#mydomain.com',['me#gmail.com'], fail_silently=False)
I can get to my reset password view (password/reset/) and after I give it my email it correctly redirects me to password/reset/done/ but it doesn't sends the email.
Here's my urls.py:
(r'^password/reset/$','django.contrib.auth.views.password_reset'),
(r'^password/reset/done/$','django.contrib.auth.views.password_reset_done'),
(r'^password/reset/confirm/$','django.contrib.auth.views.password_reset_confirm'),
(r'^password/reset/complete/$','django.contrib.auth.views.password_reset_confirm'),
(r'^password/change/$','django.contrib.auth.views.password_change'),
(r'^password/change/done/$','django.contrib.auth.views.password_change_done'),
Here's my password_reset_form.html:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/media/css/style_login.css" />
<title>Información de acceso requerida</title>
</head>
<body>
<div id="wrapper">
<h1>Recuperar password</h1>
<p>Utilice este formulario cuando desee recuperar el password para su usuario.</p>
{% if form.errors %}
<p>No hay un usuario registrado con ese correo electronico.</p>
{% endif %}
<form method="post" action="{% url django.contrib.auth.views.password_reset_done %}">
{% csrf_token %}
{{ form }}
<input class="login" type="submit" value="Recuperar" />
</form>
</div>
</body>
Any ideas? Thanks
I should have mention I'm using hostgator as my provider. So this is my settings.py
EMAIL_HOST = 'my-domain.com'
EMAIL_HOST_PASSWORD = 'my cpanel password'
EMAIL_HOST_USER = 'my cpanel user'
EMAIL_PORT = 25
EMAIL_USE_TLS = False
DEFAULT_FROM_EMAIL = 'webmaster#my-host.com'
SERVER_EMAIL = 'root#my-domain.com'
The above settings work!
In my case I created the users using create_user(). My idea was to create a bunch of accounts and then tell people they could go to the password reset form to set their password. I think it sucks if you need to tell them 'Use password "welcome123" and then don't forget to modify your password' or such.
I found out if I did not pass Password='foo' or also if I passed Password=None to create_user() password resets are not sent. This is because Django sometimes uses an empty password to know that it does not need to authenticate locally, but rather use LDAP or such.
So now I do this:
User.objects.create_user(
user_name,
email=user_email,
password=os.urandom(32),
)
And I can direct people to use the password reset function for their new accounts. I think it would be awesome if I had an option in create_user to automatically send emails for account activation to users, though!
You need to add a default from address e.g:
DEFAULT_FROM_EMAIL = 'info#mymail.com'
I see now it is in the comments but will add it here in case anyone misses them too.