Force password reset on manually created User - python

In my project I have an open signup form, where you can create your Company and all the information bellow it.
After that you can invite people to help you administrate the information of your company. To do that, my idea was to, when the logged user add another admin, I would create the user manually with a fake password and send a Reset Password request to the created email, so he can create his own password. The important code is below:
from django.contrib.auth.forms import PasswordResetForm
...
def create_admin(request):
if request.method == 'POST':
form = AdminForm(request.POST)
if form.is_valid():
email = form.cleaned_data.get("email")
random_pass = User.objects.make_random_password()
user = User(username=email, email=email, password=random_pass)
user.save()
company.add_admin(user)
reset_form = PasswordResetForm({'email': email})
reset_form.save(
email_template_name="rh/password_reset_email.html",
subject_template_name="rh/password_reset_subject.txt")
return redirect('dashboard')
else:
form = AdminForm()
return render(request, 'rh/create_admin.html', {'form': form})
Unfortunately, the above code returns a Exception Type: AttributeError 'PasswordResetForm' object has no attribute 'cleaned_data'
To note:
I already have a fully working reset password feature, using everything from django and custom templates. That's why I'm trying to make this work this way
I would like to customize the email_template_name and subject_template_name, like in my code
thanks in advance

After a bit of dialog in comments I'll leave the response. The two issues were the way the password was being created and the form not being validated. This code should work:
email = form.cleaned_data.get("email")
random_pass = User.objects.make_random_password()
user = User(username=email, email=email)
user.set_password(random_pass)
user.save()
company.add_admin(user)
reset_form = PasswordResetForm({'email': email})
reset_form.is_valid()
reset_form.save(
email_template_name="rh/password_reset_email.html",
subject_template_name="rh/password_reset_subject.txt")
return redirect('dashboard')
(Note that in this code I used the form and not the view, because I'm not sure about what you did with that. If this code doesn't work please correct it.)

Related

Is there any Solution for this Login syntax>?

Ive this Django Login and Registration form
but the registration form is fetching in database auth_user but not in helloworld_register
This is my Registration code
def Register(request):
if request.method =='POST':
username=request.POST['username']
email=request.POST['email']
first_name=request.POST['first_name']
last_name=request.POST['last_name']
password1=request.POST['password1']
password2=request.POST['password2']
if User.objects.filter(email=email).exists():
messages.info(request, 'uh oh..:( This Email is Already Taken ')
print('emailtaken')
return redirect('/Register')
elif User.objects.filter(first_name=first_name).exists():
messages.info(request, 'uh oh..:( This Name is Already Taken ')
print('Name taken')
return redirect('/Register')
user=User.objects.create_user(username=username, email=email,first_name=first_name,last_name=last_name,password=password1)
user.save();
messages.info(request, 'Registration complete Login to continue ..:)')
print('user created')
return redirect('/LOGIN')
return render(request, 'Register.html')
And this is my Login Code
def LOGIN(request):
if request.method=='POST':
email=request.POST['email']
password1=request.POST['password1']
user=auth.authenticate(email=email,password1=password1)
#user.save();
if user is not None:
auth.LOGIN(request,user)
return redirect('LOGIN')
else:
messages.info(request, 'mmm :( Invalid Credentials ')
return redirect('LOGIN')
Even though if i try Logging in with registered credentilals im unable to login
First of all, I would like to correct the terminology. Both snippets you provided are not Forms but Views. And 'auth_user' is not a database, its a table, as I will assume for 'helloworld_register'.
Related to your first problem, it seems that you are using Django's default User model. And by default this model uses 'auth_user' both to create and retrieve objects.
If you want to change defaults, you are going to need a custom user model, in fact here is a quote from Django documentation about such:
If you’re starting a new project, it’s highly recommended to set up a
custom user model, even if the default User model is sufficient for
you. This model behaves identically to the default user model, but
you’ll be able to customize it in the future if the need arises
As for your second issue, take a look at this example. I see a few errors in your snippet, such as:
user=auth.authenticate(email=email,password1=password1)
# there is no field password1 in the User model.
if user is not None:
auth.LOGIN(request,user) # Wrong call do login() method
return redirect('LOGIN') # You want to redirect to some other place
Therefore you are probably looking for something like this:
(Also, do not ignore good practices such as views names in snake_case)
from django.contrib.auth import authenticate, login
from django.shortcuts import redirect
def my_view(request):
email= request.POST['email']
password = request.POST['password1']
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
redirect('/your/app/index')
else:
messages.error(request, 'mmm: Invalid Credentials.')
redirect('/back/to/login')

Login page is verifying all users as good Django

I'm trying to build a login page in Django. But whenever I try to authenticate the user it doesn't work. The user passes each time even if the user doesn't exist. Any help I would really appreciate it!
def login(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
form = CreateUserForm()
return render(request,
"leadfinderapp/login.html",
context={"form":form})
The user isn't actually getting authenticated, you just aren't handling errors in the form. The function is just rendering the "leadfinderapp/login.html" template again regardless of the user's data entered.
To handle errors in the form, you need to have a
if form.is_valid():
# submit information and login
else:
# re render form with errors
You should look into using Django All Auth to handle your authentication (https://django-allauth.readthedocs.io/en/latest/installation.html) it's customizable but handles a lot of the work for you - just like Django itself!

Django password-only login

I'm currently working on a project for which clients should be able to login to their account using only a single 'keycode' or password, without their username. Security is not really an issue, as the tool is mostly for internal use. The user passwords will be inserted by an admin, so there will be no login collisions. How can I skip the username part of django's authentication and use only a keycode?
for your login you can use the username instead of password if no security is needed. Then get a form in your template and in your Django view :
if request.method == "POST":
form = ConnexionForm(request.POST)
if form.is_valid():
username = form.cleaned_data["Username"]
user = authenticate(username=username, password=username)
if user:
login(request, user)
UserAuthentified = True
else:
Error = True
else:
Error = True
else:
form = ConnexionForm()
You can get the username where you want in your template buy loading it in Django (and then use locals()):
request.user.username
Hope it answer to your question.
You can create all users with the same (hardcoded) password and then create a view for login which receives only the passcode (I.e. the username) and re-direct it to a real login form with the pre-defined password

Django authenticate method return None

I've read a lot topics about this problem but still can't fix problem.
I am going by Tango With Django tutorial (part 9) and get strange problem.
When I create user, I can't then get user object using authenticate method.
GitHub project: (link)
This is my register function from views:
def register(request):
# A boolean value for telling the template whether the registration was
# successful.
# Set to False initially. Code changes value to True when registration
# succeeds.
registered = False
# If it's a HTTP POST, we're interested in processing form data.
if request.method == 'POST':
# Attempt to grab information from the raw form information
# Note that we make use of both UserForm and UserProfileForm
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(data=request.POST)
# If the two forms are valid...
if user_form.is_valid() and profile_form.is_valid():
# Save the user's form data to the database.
user = user_form.save()
# Now we hash the password with the set_password method.
# Once hashed, we can update the user object
user.set_password(user.set_password)
user.save()
# Now sort out the UserProfile instance.
# Since we need to set the user attribute ourselves, we set
# commit=False
# This delays saving the model until we're ready to avoid
# integrity problems.
profile = profile_form.save(commit=False)
profile.user = user
# Did the user provide a profile picture?
# If so, we need to get it from the input form and put it in the
# UserProfile
if 'picture' in request.FILES:
profile.picture = request.FILES['picture']
# Now we save the UserProfile model instance
profile.save()
# Update our variable to tell the template registration was
# successful
registered = True
# Invalid form or forms - mistakes or something else?
# Print problems to the terminal.
# They'll also shown to the user
else:
print user_form.errors, profile_form.errors
# Not a HTTP POST, so we render out form using two ModelForm instances.
# These forms will be blank, ready for user input.
else:
user_form = UserForm()
profile_form = UserProfileForm()
context_dict = {
'user_form': user_form,
'profile_form': profile_form,
'registered': registered
}
# Render the template depending on the context.
return render(request, 'rango/register.html', context_dict)
user_login function from views:
def user_login(request):
# If the request is a HTTP POST, try to pull out the relevant information
if request.method == 'POST':
# Gather the username and password provided by the user.
# This information is obtained from the login form.
# We use request.POST.get('<variable>') as opposed to
# request.POST['variable'], because the
# request.POST.get('<variables>') return None, if the value does not
# exist, while the request.POST['<variable>'] will raise
# key error exception
username = request.POST.get('username')
password = request.POST.get('password')
# Use Django's machinery to attempt to see if the username/password
# combination is valid - a User object is returned if it is.
user = authenticate(username=username, password=password)
# user = User.objects.get(username='user1')
print user
# If we have a User object, the details are correct.
# If None (Python's way of representing the absence of a value), no
# user with matching credentials was found.
if user:
# Is the account active? It could have been disabled
if user.is_active:
# If the account is valid and active, we can log the user in.
# We'll send the user back to the homepage
login(request, user)
return redirect('rango:index')
else:
# An inactive account was user - no logging in
return HttpResponse("Your Rango account is disabled.")
else:
# Bad login details were provided. So we can't log the user in.
print "Invalid login details: {0}, {1}".format(username, password)
return HttpResponse("Invalid login details supplied")
# The request is not a HTTP POST, so display the login form.
# This scenario would most likely be a HTTP GET.
else:
# No context variables to pass to the template system, hence
# the blank dictionary object..
return render(request, 'rango/login.html')
This is the code in Tango with django
user.set_password(user.password)
user.save()
And your's is
user.set_password(user.set_password)
user.save()
Try to replace set_password with password.

Built-in view login : Error handling and good practice

I would like to use the Django's built-in login view : django.contrib.auth.views.login
This view does a great job. It detects when a login is wrong and when the account is not yet validated BUT the error messages are very short.
For a not activated account:
This account is inactive.
Do you know the proper way to be more verbose?
I prefer something like:
This account is inactive. An email was sent to you with an activation link.
Actually, I do the login by myself and I pass to the template an error context:
context = {}
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
user = authenticate(username=email, password=password)
if user is not None:
if user.is_active:
login_django(request, user)
return redirect('consumer.views.dashboard')
else:
context = {'error': 'disable_account'}
else:
context = {'error': 'invalid_account'}
return render(request, 'login.html', context)
and in the template I can check what kind of error is it.
The behavior you are reporting is actually not due to the django.contrib.auth.views.login, but to the form it uses.
In django.contrib.auth.forms.AuthenticationForm:
error_messages = {
'invalid_login': _("Please enter a correct %(username)s and password. "
"Note that both fields may be case-sensitive."),
'inactive': _("This account is inactive."),
}
I think you have two options:
You subclass the form django.contrib.auth.forms.AuthenticationForm, change error_messages, and pass the new form to the login view as argument of authentication_form.
If you use translation, you can translate the string "This account is inactive." to the string you want.
It seems to me that the first option is the best practice since translation should not be used to change messages' content.

Categories

Resources