Django Registration - using extended usercreation form. The login is activated before clicking the activation link - django-registration

I have a registraion form with the basic details and an extended user form with aditional field. The registration works fine, the mail is sent with actiavtion link. But before the activation link is clicked the login in active. I can login with the usernama and password i used for regsitraion even before the activation link is clicked.
Could someone please help and let me know where i am missing:
def register(request):
if request.method == 'POST':
form = ExtentedUserCreationForm(request.POST)
profile_form = UserProfileForm(request.POST)
if form.is_valid() and profile_form.is_valid():
profile = profile_form.save(commit=False)
user = form.save(commit=False)
user.is_active = False
profile.user = user
profile.save()
current_site = get_current_site(request)
mail_subject = 'Activate your account.'
message = render_to_string('registration/acc_activate_email.html', {
'user': user,
'profile': profile,
'domain': current_site.domain,
'uid':urlsafe_base64_encode(force_bytes(user.pk)),
#'uid':urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token':account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(
mail_subject, message, 'spraysyndb-support#uni-due.de',to=['spraysyndb-support#uni-due.de']
)
email.send()
return render(request, 'thankyou.html')
#return HttpResponse('Welcome to the SpraysynDB, you would receive an confirmation from the admin. Thank you')
else:
form = ExtentedUserCreationForm()
profile_form = UserProfileForm()
context = {'form': form, 'profile_form': profile_form}
return render(request, 'registration/regform.html', context )
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.save()
auth_login(request, user)
return render(request, 'userlogindetails.html')
#return HttpResponse('Thank you for your email confirmation. Now you can login your account at www.spraysyndb/login.de')
else:
return HttpResponse('Activation link is invalid!')

Related

Reduce the redundandant code in django model form

I have lot of code repeated here how can i modify such that there is only there is less redundant code in my model forms? the only difference here is the user_type in save method. which is admin user and the customer user.
class AdminUserCreateModelForm(UserCreationForm):
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
email = forms.EmailField(required=True)
class Meta(UserCreationForm.Meta):
model = User
def clean_email(self):
email = self.cleaned_data.get("email")
if User.objects.filter(email__iexact=email).exists():
self.add_error("email", "A user with this email already exists.")
return email
def clean_username(self):
username = self.cleaned_data.get('username')
if User.objects.filter(username__iexact=username).exists():
raise forms.ValidationError('Username Already Exists')
return username
def save(self):
user = super().save(commit=False)
user.is_admin = True
user.first_name = self.cleaned_data.get('first_name')
user.last_name = self.cleaned_data.get('last_name')
user.email = self.cleaned_data.get('email')
user.save()
admin = User.objects.create(user=user)
admin.phone_number = self.cleaned_data.get('phone')
admin.save()
return user
class CustomerUserCreateModelForm(UserCreationForm):
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
class Meta(UserCreationForm.Meta):
model = User
def clean_email(self):
email = self.cleaned_data.get("email")
if User.objects.filter(email__iexact=email).exists():
self.add_error("email", "A user with this email already exists.")
return email
def clean_username(self):
username = self.cleaned_data.get('username')
if User.objects.filter(username__iexact=username).exists():
raise forms.ValidationError('Username Already Exists')
return username
def save(self):
user = super().save(commit=False)
user.is_customer = True
user.first_name = self.cleaned_data.get('first_name')
user.last_name = self.cleaned_data.get('last_name')
user.email = self.cleaned_data.get('email')
user.save()
customer = User.objects.create(user=user)
customer.phone_number = self.cleaned_data.get('phone')
customer.save()
return user

How to rewrite django admin login view?

This is my custom login view where user can only login if their email verified. I also added two step verification in my login view. is there any way where I can implement this view in django admin login ?
def login_view(request):
username = None
password = None
two_factor = None
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
otp = request.POST.get('auth_code')
user = authenticate(request, username=username, password=password)
User = get_user_model()
if user is not None and user.is_active:
user_mail = user.userprofile.filter(
user=user, email_confirmed=True)
two_factor = user.userprofile.filter(
user=user, two_factor=True)
for i in two_factor:
....my two factor code
if user_mail and two_factor:
if secret_code == otp:
login(request, user)

why user’s session is not expired when the user’s Web browser is closed in Django?

I developed a website using Django. I have used the 'Remember me' checkbox on the login page. If a user logged in to their account/page without checking the 'Remember me' option, the session is not expiring when the browser is closed. I have used request.session.set_expiry(0).But the session is not expiring.
When the user clicks the checkbox(Remember me option), the session works properly.
Also, I used the user_passes_test decorator in order to prevent the login user to go back to the login page and register page, etc.
views.py
#user_passes_test(user_is_not_logged_in, login_url='individual_homes', redirect_field_name=None)
def logins(request):
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
remember_me = request.POST.get('remember')
print(remember_me)
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
if user.type == "individual":
details = IndividualProfile.objects.filter(user_id=request.user.id)
if not details:
if not remember_me:
request.session.set_expiry(0)
return redirect("individual_home")
else:
request.session.set_expiry(30)
return redirect("individual_home")
else:
if not remember_me:
request.session.set_expiry(0)
return redirect("individual_homes")
else:
request.session.set_expiry(30)
return redirect("individual_homes")
else:
return render(request, "login.html", {'msg': "Invalid Credentials"})
return render(request, "login.html")
Can anyone suggest a solution for this.

Django PostgreSQL - the password isn't saved to the database

I have a custom User model and a function in views.py to handle the registration. when I register a user with Postman for example all the user data is stored in the database correctly but the password -field remains empty. I think that causes the problem when I try to use a simple login -page - it never accepts my credentials (because there is no password in the database). Any ideas why the password isn't saved and how to fix it?
I have a function like this in views.py when registering a new user:
def register(response):
if response.method == 'POST':
form = RegisterForm(response.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db()
user.id = form.cleaned_data.get('id')
user.save()
username = form.cleaned_data.get('email')
password = form.cleaned_data.get('password')
user = authenticate(username=email, password=password)
return HttpResponse(status=201)
else:
form = RegisterForm()
return HttpResponse(status=400)
And this is my custom user model:
class UserManager(BaseUserManager):
def create_user(self, email, password):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('A user must have a email.')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
Edit. Here is my RegisterForm:
User = get_user_model()
class RegisterForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email', 'id', 'gender', 'height', 'weight']
def clean_email(self):
'''
Verify email is available.
'''
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean_id(self):
'''
Verify id is available.
'''
id = self.cleaned_data.get('id')
qs = User.objects.filter(id=id)
if qs.exists():
raise forms.ValidationError("id is taken")
return id
def clean(self):
'''
Verify both passwords match.
'''
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_2 = cleaned_data.get("password_2")
if password is not None and password != password_2:
self.add_error("password_2", "Your passwords must match")
return cleaned_data
And here is the model:
class CustomUser(AbstractBaseUser):
is_active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
gender = models.CharField(null=True, blank=True, max_length=20)
height = models.CharField(null=True, blank=True, max_length=3)
id = models.CharField(primary_key=True, unique=True, blank=False, max_length=100)
email= models.EmailField(max_length=100, unique=True, null=False, blank=False)
weight = models.CharField(max_length=3, null=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # Email & Password are required by default.
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
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
#property
def is_staff(self):
"Is the user a member of staff?"
return self.staff
#property
def is_admin(self):
"Is the user a admin member?"
return self.admin
objects = UserManager()
And soon after editing my question I noticed I was missing the save function from the RegisterForm class. Adding this solved the problem:
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password"])
if commit:
user.save()
return user

What is the purpose of the UID within this Django Sign Up Function

I am learning how to create a django sign up page and I am at the point of creating an email verification. I am trying to use the code snippet here:
def usersignup(request):
if request.method == 'POST':
form = UserSignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
email_subject = 'Activate Your Account'
message = render_to_string('activate_account.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(email_subject, message, to=[to_email])
email.send()
return HttpResponse('We have sent you an email, please confirm your email
but I do not know what purpose the uid serves. Why is encoding the user model object in the verification email necessary?

Resources