can someone give me a hand and example this script? django - python

I found a script online which helps me changing login to use both username and email instead of just username, but there are quite a lot of parts which I don't really understand.
Like, I understand pretty much what each line means but I don't get why by doing that would make my login work with email.
class EmailBackend(object):
def authenticate(self, username=None, password=None):
user_cls = get_user_model()
try:
user = user_cls.objects.get(email=username)
if user.check_password(password):
return user
except user_cls.DoesNotExist:
return None
except:
return None
def get_user(self, user_id):
user_cls = get_user_model()
try:
return user_cls.objects.get(pk=user_id)
except user_cls.DoesNotExist:
return None
Thanks in advance.

Check comments :-
class EmailBackend(object):
def authenticate(self, username=None, password=None):
user_cls = get_user_model() #Getting user object in one variable
try:
user = user_cls.objects.get(email=username) #Check any user exist with input email(username) with database email(consider as an username)
if user.check_password(password): #if user match then check is password match or not
return user #If both email and password match then return user information
except user_cls.DoesNotExist: #if user not exist then return None
return None
except: #got any error in middle return None
return None
def get_user(self, user_id):
user_cls = get_user_model() #Get user object in one variable
try:
return user_cls.objects.get(pk=user_id) #check user with this user_id exist or not, may be PK (some unique id consider as an user_id)
except user_cls.DoesNotExist: #if user_id(PK) not exist return None
return None

Related

Django - Login with email or username not working

In my project, I implement a login system where a user can login using their username or their email. I basically try to find whether a users email is inserted into the form field "usernameOrEmail" or whether it is their username entered in the "usernameOrEmail" field. I then log them in if a user is found.
Here is my code:
def login(request):
context = {}
if request.method == "POST":
isFound = ""
form = LoginForm(request.POST)
if form.is_valid():
try:
user = User.objects.get(username=form.cleaned_data.get("usernameOrEmail"))
isFound = "usernameFound"
except User.DoesNotExist:
try:
user = User.objects.get(email=form.cleaned_data.get("usernameOrEmail"))
isFound = "emailFound"
except User.DoesNotExist:
isFound = "nothingFound"
if isFound == "usernameFound":
print("USERNAME FOUND!")
user = auth.authenticate(username=form.cleaned_data.get("usernameOrEmail"), password=form.cleaned_data.get("password"))
if user is not None:
auth.login(request, user)
return redirect('home')
else:
context["error"] = "Oops, username/email or password provided is invalid"
elif isFound == "emailFound":
print("EMAIL FOUND")
user = auth.authenticate(email=form.cleaned_data.get("usernameOrEmail"), password=form.cleaned_data.get("password"))
if user is not None:
print("YES")
auth.login(request, user)
return redirect('home')
else:
print("NO")
context["error"] = "Oops, username/email or password provided is invalid"
else:
context["error"] = "Oops, username/email or password provided is invalid"
else:
context["error"] = "Please enter valid form data"
else:
form = LoginForm()
Weirdly, the terminal return the print statement "EMAIL FOUND" meaning that the email of a user was found, however the "NO" print statement is also printed, and the message "Oops, username/email or password provided is invalid" is returned in the template.
The other weird thing is that this system works for the users username, meaning when I enter a users username into the "usernameOrEmail" field, and I enter the correct password, the user is logged in. Anybody know the issue? thank you.
The standard authentication backend only works with a username and password. Indeed, the authenticate method [GitHub] of the ModelBackend is implemented as:
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
This is however not a problem. You can just implement this with:
def login(request):
context = {}
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
try:
user = User.objects.get(username=form.cleaned_data['usernameOrEmail'])
except User.DoesNotExist:
try:
user = User.objects.get(email=form.cleaned_data['usernameOrEmail'])
except User.DoesNotExist:
user = None
if user is not None:
user = auth.authenticate(username=user.username, password=form.cleaned_data['password'])
if user is not None:
auth.login(request, user)
return redirect('home')
else:
context['error'] = 'Oops, username/email or password provided is invalid'
else:
context['error'] = 'Please enter valid form data'
else:
form = LoginForm()
# …

How to check a plain password to a hashed password at login in django

I have hashed password (using set_password) in my database table , I want to compare the hashed-password with my plain password using check_password to login successfully.
views.py/login view
def logauth(request):
if request.method == "POST":
email = request.POST['username']
password = request.POST['password']
user = authenticate(request, email=email, password=password)
if user is not None:
messages.error(request, 'if part : user is not None')
login(request, user)
return redirect('emp')
else:
messages.error(request, 'else part : user is None')
return redirect('login_url')
else:
messages.error(request, 'Please provide valid credentials')
return render(request, 'registration/login.html')
backends.py
class MyBackEnd(object):
def authenticate(self, request, email=None, password=None):
existing_user = RegAuth.objects.get(email=email,password=password)
if not existing_user:
# Checking the user Regauth Custom DB.
user_data = RegAuth.objects.get(email=email,password=password)
if email == user_data.email:
user = RegAuth.objects.create_user(email=email, password=password)
user.save()
return user
else:
return None
else:
return existing_user
def get_user(self, email):
try:
return RegAuth.objects.get(email=email)
except Exception as e:
return False

how to get data of another field in wtform validate_?

I am trying to do password validation on wtform like this:
email = StringField('Email', validators=[DataRequired(), Email()])
def validate_password(self, password):
print(self)
user = dbSession.execute(
"SELECT * FROM users WHERE email = :email",
{"email": self.email.data}
).fetchone()
print(user)
if not bcrypt.check_password_hash(user.password, password.data):
raise ValidationError('Incorrect Password.')
i want to get the email from other field, but i guess it's not working, i tried email.data but it isn't defined. also, it's not logging in console. in js, you log an object like this. I wanted to see the self's properties and the user, i want to log like this in python.
console.log('user =', user);
help?
This answer reformulates this little snippet
Sometimes you are in the situation where you need to validate a form with custom logic that can not necessarily be reduced to a validator on a single field. A good example are login forms where you have to make sure a user exists in the database and has a specific password.
class LoginForm(Form):
email = TextField('Email', [validators.InputRequired(), Email()])
password = PasswordField('Password', [validators.InputRequired()])
def __init__(self, *args, **kwargs):
Form.__init__(self, *args, **kwargs)
self.user = None
def validate(self):
rv = Form.validate(self)
if not rv:
return False
user = User.query.filter_by(
email=self.email.data).first()
if user is None:
self.email.errors.append('Unknown email')
return False
if not bcrypt.check_password_hash(user.password, self.password.data):
self.password.errors.append('Invalid Password')
return False
self.user = user
return True

Django: Superuser username doesn't show up in Users table

I am new to Django, and currently experimenting with creating a custom user. Apart from some additional fields that my custom user has, I implemented that email is used for authentication instead of username. Also, username is generated by concatenating first name, last name and a number so that unique username would be obtained. Now, I've checked the email authentication and username generation which seems to work, however, the problem that I face is when I enter the Django Administration panel and open User table instead of 'admin' username there is blank. Furthermore, other fields, such as first name, last name, etc don't show for all users.
Screenshot of the admin panel
Custom user and pre_save method for username generation (users.models.py):
class User(AbstractUser):
personal_no = models.CharField(verbose_name=_('personal number'), max_length=13)
address = models.CharField(verbose_name=_('address'), max_length=50)
#receiver(pre_save, sender=User)
def generate_username_callback(**kwargs):
instance = kwargs['instance']
if not instance.pk:
instance.username = generate_username(instance.first_name, instance.last_name)
def generate_username(first_name, last_name):
val = "{0}{1}".format(first_name, last_name).lower()
count = 0
while True:
if count == 0 and User.objects.filter(username=val).count() == 0:
return val
else:
new_val = "{0}{1}".format(val, count)
if User.objects.filter(username=new_val).count() == 0:
return new_val
count += 1
if count > 10000:
raise Exception("Too many users named {0}".format(val))
Custom backend for email authentication (users.backends.py):
class EmailBackend(object):
def authenticate(self, username=None, password=None, **kwargs):
try:
user = User.objects.get(email=username)
except User.DoesNotExist:
return None
else:
if getattr(user, 'is_active', False) and user.check_password(password):
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
users.admin.py:
from django.contrib import admin
from .models import User
admin.site.register(User)
settings.py:
AUTHENTICATION_BACKENDS = [
'users.backends.EmailBackend'
]
AUTH_USER_MODEL = 'users.User'
I am using Django 1.10.4
The first_name and last_name fields are missing from the table on the changelist field, because you have not specified a ModelAdmin class when you registered your model. To use the default UserAdmin class, you would do:
from django.contrib.auth.admin import UserAdmin
admin.site.register(User, UserAdmin)

AttributeError: 'SelectQuery' object has no attribute 'is_active'

I'm trying to learn the Peewee ORM in combination with Flask by following the Flask Mega Tutorial. In part 5 of the tutorial I create a login using OpenID. After overcoming a bunch of hurdles already I now get an AttributeError in the function pasted below on the following line: login_user(user, remember = remember_me).
#oid.after_login
def after_login(resp):
if resp.email is None or resp.email == "":
flash('Invalid login. Please try again.')
return redirect(url_for('login'))
user = User.select().where(User.email == resp.email)
if user.wrapped_count() == 0:
nickname = resp.nickname
if nickname is None or nickname == "":
nickname = resp.email.split('#')[0]
user = User(nickname = nickname, email = resp.email, role = models.ROLE_USER)
user.save()
remember_me = False
if 'remember_me' in session:
remember_me = session['remember_me']
session.pop('remember_me', None)
login_user(user, remember = remember_me)
return redirect(request.args.get('next') or url_for('index'))
is_active is found in my User model as follows:
class User(db.Model):
nickname = TextField()
email = TextField()
role = IntegerField(default = ROLE_USER)
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return self.id
def __repr__(self):
return '<User %r>' % (self.nickname)
I have no clue what I'm doing wrong here though. Could anybody give me a helping hand in what I'm doing wrong here?
All tips are welcome!
As the error suggests, user = User.select().where(User.email == resp.email) gives you back a SelectQuery, not an instance of User. You'll want to include an additional method call to actually fetch the record, something like .first(). first will return either an instance of User or None.
This would allow you to slightly adjust your code:
user = User.select().where(User.email == resp.email).first()
if not user: # or if user is None:
nickname = resp.nickname
...

Categories

Resources