My Custom User authentication wont work - python

I created a custom user model for my Django project so that the user could login in with their email. However, the authentication wouldn't work.
Here is my code:
Views:
def login_view(request):
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data.get('email')
password = form.cleaned_data.get('password')
user = authenticate(usename=email, password=password)
if user:
print(True)
login(request, user)
return redirect('/account/')
else:
print(str(password)+" "+str(email))
print(False)
else:
form = LoginForm()
return render(request, 'users/login.html',{'form': form})
my backend:
def authenticate(self, username=None, password=None,):
try:
user = User.objects.get(email=username)
if user.check_password(password):
return True
except User.DoesNotExist:
return True
def get_user(self, user_id):
try:
user = User.objects.get(pk=user_id)
if user.is_active:
return user
return None
except User.DoesNotExist:
return None
My User Model:
class UserManager(BaseUserManager):
def _create_user(self, first_name, last_name, username, email, is_admin, password=None, **extra_fields):
"""
creates a User with first name, last name, username, email, password
"""
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(
first_name=first_name,
last_name=last_name,
username=username,
email=email,
is_admin=is_admin,
is_active=True,
**extra_fields,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, first_name, last_name, username, email, password, **extra_fields):
return self._create_user(
first_name,
last_name,
username,
email,
False,
password,
**extra_fields
)
def create_superuser(self, first_name, last_name, username, email, password=None, **extra_fields):
return self._create_user(
first_name,
last_name,
username,
email,
True,
password,
**extra_fields
)
class User(AbstractBaseUser):
first_name = models.CharField(
max_length=256,
unique=False,
verbose_name='first name',
)
last_name = models.CharField(
verbose_name='last name',
max_length=256,
unique=False,
)
username = models.CharField(
verbose_name='username',
max_length=256,
unique=False,
)
email = models.EmailField(
verbose_name='email',
max_length=256,
unique=True,
)
is_active = models.BooleanField(
default=True,
)
is_admin = models.BooleanField(
default=False,
)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [
'first_name',
'last_name',
'username',
]
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def get_full_name(self):
full_name = "{} {}".format(self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
def __str__(self): # __unicode__ on Python 2
return self.email
def email_user(self, subject, message, from_email):
send_mail(subject, message, from_email, [self.email])
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
def has_perm(self, perm, obj=None):
return self.is_admin
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
My settings:
AUTH_USER_MODEL = 'custom_user.User'
AUTHENTICATION_BACKENDS = ('custom_user.backends.UserAuth', )
My Forms:
email = forms.CharField(
widget=forms.TextInput(attrs={'class': 'registerforms', 'placeholder': 'Email'}),
label='',
)
password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'registerforms', 'placeholder': 'Password'}),
label='',
)
I do not get an error however it doesn't log the user in

Related

How to populate DB from Facebook response using python-social-auth

I have Django with python-social-auth installed.
My custom user model:
class User(AbstractUser):
"""Custom User model."""
username = None
email = models.EmailField(blank=False, unique=True, verbose_name=_("Email"))
facebook_link = models.URLField(blank=True, verbose_name=_("Facebook profile link"))
contacts = models.CharField(blank=True, max_length=250, verbose_name=_("Contacts"))
hometown = models.CharField(blank=True, max_length=250, verbose_name=_("Hometown"))
start_coordinates = models.CharField(blank=True, max_length=100, verbose_name=_("Start coordinates"))
avatar = ProcessedImageField(
upload_to="avatar/",
format="JPEG",
options={"quality": 80},
default="avatar/default_avatar.jpg",
verbose_name=_("Image"),
)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
def __str__(self):
"""Model representation."""
return self.email
def get_absolute_url(self):
"""Get url to User's model instance."""
return reverse_lazy("public-profile", kwargs={"user_id": self.pk})
def get_full_name(self):
"""Concatenate fist and last names."""
full_name = " ".join([self.first_name, self.last_name])
return full_name.strip()
get_full_name.short_description = _("Full name")
class Meta:
verbose_name = _("User")
verbose_name_plural = _("Users")
Managers.py
class UserManager(BaseUserManager):
"""
Custom user model manager where email is the unique identifiers
for authentication instead of usernames.
"""
def create_user(self, email, password=None, **extra_fields):
"""Create and save a User with the given email and password."""
if not email:
raise ValueError(_("Email required"))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""Create and save a SuperUser with the given email and password."""
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
if extra_fields.get("is_staff") is not True:
raise ValueError(_("Superuser must have is_staff=True."))
if extra_fields.get("is_superuser") is not True:
raise ValueError(_("Superuser must have is_superuser=True."))
return self.create_user(email, password, **extra_fields)
I do succesfull authentication with Facebook with this code:
AUTHENTICATION_BACKENDS = (
'social_core.backends.github.GithubOAuth2',
'social_core.backends.google.GoogleOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_USER_MODEL = 'accounts.User'
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
SOCIAL_AUTH_LOGIN_REDIRECT_URL = 'home'
SOCIAL_AUTH_LOGIN_URL = 'login'
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', 'user_link', 'user_hometown']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'id, name, email, picture.type(large), link, hometown'
}
SOCIAL_AUTH_FACEBOOK_EXTRA_DATA = [
('name', 'name'),
('email', 'email'),
('picture', 'avatar'),
('link', 'facebook_link'),
('hometown', 'hometown'),
]
As a result, I have a new user instance created in DB with the automatically populated fields:
fist_name, last_name, email.
How do I can populate the rest of fields (facebook_link, hometown) with data from response?

create a superuser and adminuser using django restframework

i have a custom user model and i want to create a superuser from a view right, am currently using django restframework, below is my custom model and serializer with the views.
model.py
class CompanyUserManager(UserManager):
def _create_user(self, username, email, password, **extra_fields):
"""
Create and save a user with the given username, email and passsword
"""
if not username:
raise ValueError('The given username must be set')
if not email:
raise ValueError('The email must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(username=username, email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username: str, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', False)
return self._create_user(username, email, password, **extra_fields)
def create_admin_user(self, username: str, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault('is_admin', True)
# if extra_fields.get('is_staff') is not True:
# raise ValueError('Super user must have is_staff=True')
# if extra_fields.get('is_admin') is not True:
# raise ValueError('Super user must have is_admin=True')
# if extra_fields.get('is_superuser') is True:
# raise ValueError('Superuser must have is_superuser=False')
return self._create_user(username, email, password, **extra_fields)
def create_superuser(self, username: str, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_admin', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Super user must have is_staff=True')
if extra_fields.get('is_admin') is not True:
raise ValueError('Super user must have is_admin=True')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True')
return self._create_user(username, email, password, **extra_fields)
# Create your models here.
class CompanyUser(AbstractBaseUser, PermissionsMixin):
username_validator = UnicodeUsernameValidator()
username = models.CharField(_('username'), max_length=150, unique=True, help_text='Required, 150 characters or fewer', error_messages={'unique ': ' a User with this user name is already registered'}, validators=[username_validator])
email = models.EmailField(_('email address'), blank=False, unique=True)
phone = models.CharField(_('phone'), max_length=20, blank=True, null=True)
is_staff = models.BooleanField(_('staff status'), default=True, help_text='Designated user can login using this account')
is_active = models.BooleanField(_('active'), default=True, help_text='Designated whether this user should be treated as active')
is_superuser = models.BooleanField(_('superuser'), default=False, help_text='Designated user can login using this account')
is_admin = models.BooleanField(_('admin'), default=False, help_text='Designated user can login using this account')
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
email_verified = models.BooleanField(_('email_verified'), default=False,)
objects = CompanyUserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD: str = 'email'
REQUIRED_FIELDS = ['username', 'phone']
#property
def token(self):
token = jwt.encode({
'username': self.username,
'email': self.email,
'exp': datetime.utcnow() + timedelta(hours=24)},
settings.SECRET_KEY, algorithm='HS256')
return token
#property
def staff(self):
return self.is_staff
#property
def admin(self):
return self.is_admin
#property
def active(self):
return self.is_active
#property
def owner(self):
return self.is_superuser
serializer.py
class RegisterSerializer(serializers.ModelSerializer):
# username = serializers.CharField(max_length=100)
# email = serializers.EmailField()
# password = serializers.CharField(max_length=100)
# password2 = serializers.CharField(max_length=100)
# def validate(self, data):
# if data['password'] != data['password2']:
# raise serializers.ValidationError('Passwords must match')
# return data
password = serializers.CharField(max_length=100, write_only=True)
class Meta:
model = CompanyUser
fields = ("id", "username", "email", "password", "is_active")
extra_kwargs = {"password": {"write_only": True}}
def create(self, validated_data):
user = CompanyUser(**validated_data)
user.set_password(validated_data["password"])
user.save()
return user
def create_superuser(self, validated_data):
user = CompanyUser(**validated_data)
print(validated_data)
if "password" in validated_data:
from django.contrib.auth.hashers import make_password
validated_data["password"] = make_password(validated_data["password"])
user.set_password(validated_data["password"])
user.is_superuser = True
user.is_admin = True
user.is_staff = True
user.save()
return user
the create_superuser isnt working, it throws a keyerror password not found
view.py
class RegisterAPIView(GenericAPIView):
"""
A view that allow company owners to create an account
"""
serializer_class = RegisterSerializer
def post(self, request, *args, **kwargs):
serializers = self.serializer_class(data=request.data)
if serializers.is_valid():
serializers.save()
# self.serializer_class.create_superuser(serializers.data)
# serializers.create_superuser(serializers.data)
return Response(serializers.data, status=status.HTTP_201_CREATED)
return Response(serializers.errors, status=status.HTTP_400_BAD_REQUEST)
so this are my codes and i cant create a superuser from the endpoint, i dont want to use the django cli, any help please šŸ˜Œ

When i create a user from admin page , i can't login

In django i am building a user db but i have a problem with this .
When i try python3 manage.py createsuperuser this works fine but when i try creating user with admin page i can create user but user's password is not hashing and in login template i can't login .
Django version 4.0
login views.py :
def loginacc(request):
if request.method == "POST":
tcNo = request.POST.get("tcNo")
password = request.POST.get("password")
user = authenticate(request, tcNo=tcNo, password=password)
if user is not None:
login(request, user)
return render(request, "home/home.html")
else:
return render(request, "accounts/accounts.html", {"error": "Name or password is wrong . "})
return render(request, 'accounts/accounts.html')
student models.py :
class Student(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
tcNo = models.IntegerField(unique=True)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
nickname = models.CharField(max_length=255, blank=True, null=True)
objects = StudentBaseUserManager()
USERNAME_FIELD = 'tcNo'
REQUIRED_FIELDS = ['first_name', 'last_name', 'email', "nickname"]
def save(self, *args, **kwargs):
self.nickname = self.first_name + "-" + self.last_name
return super(Student, self).save(*args, **kwargs)
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
def __str__(self):
return self.email
class StudentBaseUserManager(BaseUserManager):
def create_user(self, tcNo, first_name, nickname, last_name, email, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
password=password,
first_name=first_name,
last_name=last_name,
tcNo=tcNo,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, tcNo, nickname, first_name, last_name, email, password):
user = self.create_user(email=email,
last_name=last_name,
nickname=nickname,
first_name=first_name,
password=password,
tcNo=tcNo,
)
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user

Creating student accounts using django admin and using them for login

Hi I wanted to create user accounts from django admin pannel and then use the email and passsword stored in the model to login?
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['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
return redirect("home")
else:
form = AccountAuthenticationForm()
context['login_form'] = form
return render(request, 'login.html', context)
forms.py
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['email']
password = self.cleaned_data['password']
if not authenticate(email=email, password=password):
raise forms.ValidationError("Invalid login")
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Users must have an email address")
user = self.model(
email=self.normalize_email(email))
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined=models.DateTimeField(verbose_name='datejoined',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)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
Please ignore the indentation, it is bit messed up as I am new to stack overflow and uploaded code for the first time.
Any sort of help would be appreciated.

adding required files to custom user when registration in django

Iā€™m really new in Django and I would like to create a register form to login user.
I would like this form have additional and required fields. the problem is when I try to fill the sign up registration directly on the web, the user is not registered, but if I do it in /admin section, the user is saved, so I have used custom user
So first I have created class in model.py file:
class Account (AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=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)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
phone_regex = RegexValidator(
regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
phone_number = models.CharField(
validators=[phone_regex], max_length=17, blank=True) # validators should be a list
role = models.CharField(max_length=50)
store = models.CharField(max_length=50)
aisle = models.CharField(max_length=50, unique=True)
user_identification = models.CharField(max_length=30, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name',
'phone_number', 'role', 'store', 'aisle', 'user_identification']
objects = MyAccountManager()
def __str__(self):
return self.email
# if user is admin, can chenge
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
#property
def staff(self):
return self.is_staff
#property
def active(self):
return self.is_active
after I have created the Account Manager in the same models.py
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, first_name, last_name,
phone_number, role, store, aisle, user_identification, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have an user name")
if not first_name:
raise ValueError("Users must have an user name")
if not last_name:
raise ValueError("Users must have an user name")
if not phone_number:
raise ValueError("Users must have an user name")
if not role:
raise ValueError("Users must have an user name")
if not store:
raise ValueError("Users must have an user name")
if not aisle:
raise ValueError("Users must have an user name")
if not user_identification:
raise ValueError("Users must have an user name")
user = self.model(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
phone_number=phone_number,
role=role,
store=store,
aisle=aisle,
user_identification=user_identification,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, first_name, last_name,
phone_number, role, store, aisle, user_identification, password=None):
user = self.create_user(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
phone_number=phone_number,
role=role,
store=store,
aisle=aisle,
user_identification=user_identification,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
then in the forms.py file I have created the register method:
class RegistrationForm(UserCreationForm):
email = forms.EmailField(
max_length=60, help_text='Required. Add a valid email address')
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
phone_number = forms.CharField(max_length=30)
role = forms.CharField(max_length=30)
aisle = forms.CharField(max_length=30)
user_identification = forms.CharField(max_length=30)
class Meta:
model = Account
fields = ["email", "username", "password1", "password2", 'first_name', 'last_name',
'phone_number', 'role', 'store', 'aisle', 'user_identification', ]
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.phone_number = self.cleaned_data['phone_number']
user.role = self.cleaned_data['role']
user.aisle = self.cleaned_data['aisle']
user.user_identification = self.cleaned_data['user_identification']
if commit:
user.save()
return user
and the view looks like that:
def registration_view(request): # request, GET from the web
form = RegistrationForm()
context = {}
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
# name = form.cleaned_data.get('email')
login(request, account)
return redirect('home')
else:
context['registration_form'] = form
else:
form = RegistrationForm()
context['registration_form'] = form
# here we inflate and return the view
return render(request, 'account/register.html', context)
I have configured in settings.py the user custom model:
AUTH_USER_MODEL = 'account.Account'
Also I have configured the admin.py file
class AccountAdmin (UserAdmin):
list_display = ('email', 'username', 'date_joined',
'last_login', 'is_admin', 'is_staff',)
search_fields = ('email', 'username',)
readonly_fields = ('date_joined', 'last_login')
filter_horizontal = ()
list_filter = ()
fieldsets = ()
admin.site.register(Account, AccountAdmin)
admin.site.register(UserProfile)
thanks a lot for your help guys!
Perhaps are you always setting commit=false in order to work with it before saving, but then always is going to avoid saving because the if sentence at the end of the Def ?
class RegistrationForm(UserCreationForm):
...
def save(self, commit=True):
user = super(RegistrationForm, self).save(**commit=False**)
user.set_password(self.cleaned_data["password1"])
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.phone_number = self.cleaned_data['phone_number']
user.role = self.cleaned_data['role']
user.aisle = self.cleaned_data['aisle']
user.user_identification = self.cleaned_data['user_identification']
**if commit:**
user.save()
return user
I hope this helps!

Categories