Django - How to authenticate a password with MD5 hash - python

So I'm trying to use the authentication method in my views, but always return "Does not exist", I'm using MD5 hash for my password field, so I don't know if thats the problem
forms.py
class LoginForm(forms.Form):
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput)
#This Method Hash the password
def clean_password(self):
clearPassNoHash = self.cleaned_data['password']
self.password = md5.new(clearPassNoHash).hexdigest()
return self.password
views.py
def auth_login(request):
args = {}
form = LoginForm(request.POST)
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
print("Exist")
else:
print("Does not exist")
I've tried with check_password() method(in my forms) that actually works
but I don't know why I'm having trouble with the authenticate()
-----------------------------UPDATE--------------------------------
Views.py
def auth_login(request):
args = {}
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
print("existe")
print user
else:
print user
args['form'] = form
return render(request, 'login/login.html', args)
forms.py
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
Other observation:
I have this in my settings.py to use my custom model
AUTH_PROFILE_MODULE = 'StudentUsers.StudentRegistration'
and this is the username field I add to my model:
class StudentRegistration(AbstractBaseUser, models.Model):
username = models.CharField(max_length = 25, null=False, default="", unique=True)

You need to get the email and password from the form's cleaned_data, not from the request directly. Read more on the cleaned_data attribute from the docs : https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.cleaned_data
password = form.cleaned_data['password']

You should not be hashing the password value yourself. That is what authenticate already does; so in effect you are hashing twice.

Related

"This field is required" keeps showing even all the input field is filled

Please help. The signup page keeps showing this field is required error. I'm a beginner. thankyouu
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, username, full_name, password=None):
if not email:
raise ValueError("Users must have an email adress")
if not username:
raise ValueError("Users must have a username")
if not password:
raise ValueError("Users must have a password")
if not full_name:
raise ValueError("Users must have a name")
user = self.model(
email=self.normalize_email(email), # return lowercase
username=username,
full_name=full_name,
)
user.set_password(password) # users set password and change password
user.full_name = full_name
user.save(using=self._db)# using the default database in settings.py
return user
def create_superuser(self, email, username, full_name, password=None):
user = self.create_user(
email=self.normalize_email(email), # return lowercase
username=username,
full_name=full_name,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db) # using the default database in settings.py
return user
class Account(AbstractBaseUser):
email = models.EmailField(
verbose_name="email",
max_length=60,
unique=True,
)
username = models.CharField(max_length=30, unique=True)
full_name = models.CharField(max_length=30, blank=True, null=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
profile_image = models.ImageField(max_length=255, null=True, blank=True, default=default_profile)
hide_email = models.BooleanField(default=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "full_name"]
objects = UserManager() # tie account to my custom user manager
def __str__(self):
return self.username
# "Does the user have a specific permission?"
def has_perm(self, perm, obj=None):
return True
# "Does the user have permissions to view the app `app_label`?"
def has_module_perms(self, app_label):
return True
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from account.forms import RegistrationForm, AccountAuthenticationForm
def register_view(request):
user = request.user
if user.is_authenticated:
return redirect('home')
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email').lower()
raw_password = form.cleaned_data.get('password1')
user = authenticate(email=email, password=raw_password)
login(request, user)
return redirect('home')
else:
form = RegistrationForm()
return render(request, 'account/register.html', {'registration_form': form})
def login_view(request):
context = {}
user = request.user
if user.is_authenticated:
return redirect("home")
if request.POST:
form = AccountAuthenticationForm(request.POST)
if form.is_valid():
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect("home")
else:
form = AccountAuthenticationForm()
context['login_form'] = form
return render(request, "account/login.html", context)
def logout_view(request):
logout(request)
return redirect("home")
forms.py
from django import forms
from django.contrib.auth import get_user_model
from .models import Account
from django.contrib.auth import authenticate
User = get_user_model()
class RegistrationForm(forms.ModelForm):
full_name = forms.CharField()
email = forms.EmailField(max_length=60, help_text='Required. Add a valid email address.')
password1 = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(widget=forms.PasswordInput, label='Confirm password')
class Meta:
model = Account
fields = (
'email',
'username',
'full_name',
'password1',
'password2',
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.email = self.cleaned_data.get('email')
user.username = self.cleaned_data.get('username')
user.full_name = self.cleaned_data.get('full_name')
if commit:
user.save()
return user
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError(f"Email {email} is already taken")
return email
def clean_username(self):
username = self.cleaned_data.get('username')
qs = User.objects.filter(username=username)
if qs.exists():
raise forms.ValidationError(f"Username {username} is already taken")
return username
def clean(self):
data = self.cleaned_data
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password2 != password1:
raise forms.ValidationError("Passwords must match")
return data
class AccountAuthenticationForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model = Account
fields = ('email', 'password')
def clean(self):
if self.is_valid():
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if not authenticate(email=email, password=password):
raise forms.ValidationError("Incorrect username or password")
The cause of the problem could be due to the username field and email field being used one in place of the other.
An example found in the code mentioned above:
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "full_name"]
The problem can be resolved by verifying and fixing these errors where the email field is used in place of username field and vice versa.
Most likely there is a error in your fields html id and name so the form validation registers it as an empty value
if request.method == "POST":
updated_request = request.POST.copy()
updated_request.update({'username': request.POST['email']})
form = RegistrationForm(updated_request)

get OneToOneField data from User models on firsttime save()

i want to extend my User models and add fields to it in another models
and i want it to save two of the form at once
each form works fine on its own but
the problem is that when i combine them the
i cant get the username from the User model
class Information(models.Model):
Username = models.OneToOneField(User, on_delete=models.CASCADE)
i tried this views.py
RegisterForm = self.form_class(request.POST)
InfoForm = self.second_form_class(request.POST)
if RegisterForm.is_valid() and InfoForm.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
email = request.POST.get('email')
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
User_obj = User(username=username, password=password, email=email, first_name=first_name,
last_name=last_name)
user = User_obj.save()
Username = username
PhoneNo = request.POST.get('PhoneNo')
Address = request.POST.get('Address')
Country = request.POST.get('Country')
Info_obj = Information(Username=Username , PhoneNo=PhoneNo, Address=Address, Country=Country)
Info_obj.save()
forms.py
class RegisterForm(forms.ModelForm):
username = forms.CharField(max_length=40)
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ["username","password", "email", "first_name", "last_name"]
class InfoForm(forms.ModelForm):
Username = forms.CharField(max_length=40, required=False)
class Meta:
model = Information
fields = ["Username","PhoneNo","Address","Country"]
did i miss something here?
it can save to the User but it doesn't save to Information model
I think the problem is with the Username on InfoForm
the problem was with the InfoForm's Username field
instead of directly getting the value from the RegisterForm
username = request.POST.get('username')
# with this code below Django demands that i need username instance from User model
Username = username
so after saving RegisterForm, i get the value from the User Database with a objects.get() method
Username = User.objects.get(username=username)
Solution
RegisterForm = self.form_class(request.POST)
InfoForm = self.second_form_class(request.POST)
if RegisterForm.is_valid() and InfoForm.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
email = request.POST.get('email')
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
User_obj = User(username=username, password=password, email=email, first_name=first_name,
last_name=last_name)
User_obj.save()
# i call the username from the User database after saving them
Username = User.objects.get(username=username)
PhoneNo = request.POST.get('PhoneNo')
Address = request.POST.get('Address')
Country = request.POST.get('Country')
Info_obj = Information(Username=Username , PhoneNo=PhoneNo, Address=Address, Country=Country)
Info_obj.save()
don't know if i had explained it correctly
Cheers

Django. Best way to have unique email in User model?

I have a UserProfile model to add some things to my User model and one thing I want to do is have unique email for users so I added an email attribute to my UserProfile model and set it to unique=True like this :
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name="profile")
email = models.EmailField(unique=True)
avatar = models.ForeignKey(Avatar)
...
I created a custom form for the registration to add some infos directly to my UserProfile :
class CreateUserForm(forms.Form):
username = forms.CharField(max_length=30, label="Pseudo")
password1 = forms.CharField(widget=forms.PasswordInput, label="Password")
password2 = forms.CharField(widget=forms.PasswordInput, label="Confirmez pwd")
email = forms.EmailField(widget=forms.EmailInput, label="E-mail")
avatar = AvatarChoiceField(widget=forms.RadioSelect, queryset=Avatar.objects.all(), label="Avatar")
def clean_username(self):
username = self.cleaned_data.get('username')
if User.objects.filter(username=username).exists():
raise forms.ValidationError("This username is already used")
return username
def clean_password2(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 != password2:
raise forms.ValidationError("Your passwords do not match")
return password1
def clean_email(self):
email = self.cleaned_data.get('email')
if UserProfile.objects.filter(email=email).exists():
raise forms.ValidationError("This email is already used")
return email
And then in my views.py I treat my form like that :
def create_user(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
username = form.clean_username()
email = form.clean_email()
password = form.clean_password2()
username = form.cleaned_data['username']
avatar = form.cleaned_data['avatar']
user = User.objects.create_user(username=username, password=password)
user.save()
user_profile = UserProfile(user=user, email=email, avatar=avatar)
user_profile.save()
else:
form = CreateUserForm()
return render(request, 'accounts/create.html', locals())
Finally I used the email of the form for my UserProfile model and not for my User model. And by this way I have a unique email for my users. And it's working.
Am I doing it right or is there a better way to achieve what I want ?
You are on the right track, the only thing that doesn't look right is that you shouldn't call clean method manually like this:
# These are not needed in your view method
username = form.clean_username()
email = form.clean_email()
password = form.clean_password2()
They are already called by form.is_valid(). See this SO question for details.

Custom authentication not logging in user with correct password

I have a user in my database with the login jim#test.com and password jimrox. I'm trying to log him in with this view:
def login(request):
email = request.POST.get("email", "")
password = request.POST.get("password", "")
user = authenticate(username=email, password=password)
My custom authentication looks partly like this:
class login(object):
def authenticate(self, username=None, password=None):
# auth user based on email
try:
user = Freelancer.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
When the user attempts to check_password() it doesn't return the user even though the password is correct. Am I meant to create my own check_password() function in the model?
Here is my model also:
class FreelancerManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
class Freelancer(AbstractBaseUser):
email = models.EmailField()
first_name = models.CharField(max_length=128, primary_key=True)
surname = models.CharField(max_length=128)
university = models.CharField(max_length=256)
verified = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
If I am meant to create my own password check, how would I do that? This is with 1.8 also.
EDIT
Here is how I add my users to the database:
views.py
def freelancer_signup(request):
if request.method == 'POST':
form = FreelancerForm(request.POST)
if form.is_valid():
freelancer = form.save(commit=False)
freelancer.save()
return render(request, 'freelancestudent/index.html')
else:
return render(request, 'freelancestudent/index.html')
else:
form = FreelancerForm()
return render(request, 'freelancestudent/freelancersignup.html', {'form': form})
forms.py
from django import forms
from models import Freelancer
class FreelancerForm(forms.ModelForm):
class Meta:
model = Freelancer
password = forms.CharField(widget=forms.PasswordInput)
fields = ('email', 'first_name', 'surname', 'university', 'password')

Django: Created django user that are extended with my django model field

Here it's my django model
class student(User):
name = models.CharField(max_length = 200)
phone_no = models.BigIntegerField()
email_id = models.EmailField()
version = models.IntegerField()
now I want to register user that are extend by my model fields.
here its my student register code
def registerStudent(request):
print request.body
if request.body:
dataDictionary = json.loads(request.body)
username = dataDictionary['username']
first_name = dataDictionary['first_name']
last_name = dataDictionary['last_name']
email = dataDictionary['email']
password = dataDictionary['password']
password1 = dataDictionary['password1']
user=User()
user.username = username
user.first_name = first_name
user.last_name = last_name
user.email = email
if password == password1:
user.set_password(password)
else:
return HttpResponse(json.dumps([{"validation": "Password does not match", "status": False}]), content_type="application/json")
user.save()
here something wrong
I want to take json as a input and create user using above model field.
I seems that you only save the user when the passwords don't match, after the return. Move the "user.save()" line one tab to the left.
The code should be:
if password == password1:
user.set_password(password)
user.save()
else:
return HttpResponse(json.dumps([{"validation": "Password does not match"
,"status": False}])
,content_type="application/json")
Now the user will be saved when password = password1, if that what you want.

Categories