initial
This commit is contained in:
0
accounts/__init__.py
Normal file
0
accounts/__init__.py
Normal file
36
accounts/admin.py
Normal file
36
accounts/admin.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from django.contrib import admin
|
||||
from accounts.models import *
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
|
||||
class UserAdmin(BaseUserAdmin):
|
||||
list_display = (
|
||||
'username',
|
||||
'email',
|
||||
'is_verified',
|
||||
'role',
|
||||
'created',
|
||||
)
|
||||
list_filter = (
|
||||
'is_superuser',
|
||||
'is_verified',
|
||||
'created',
|
||||
'role'
|
||||
)
|
||||
search_fields = ('username', 'email')
|
||||
|
||||
# Add the is_verified field to the fieldsets
|
||||
fieldsets = (
|
||||
(None, {'fields': ('username', 'password')}),
|
||||
('Personal Info', {'fields': ('first_name', 'last_name', 'email', 'is_verified', 'role')}),
|
||||
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
|
||||
('Important dates', {'fields': ('last_login', 'date_joined')}),
|
||||
)
|
||||
|
||||
# Register your User model with the modified UserAdmin class
|
||||
admin.site.register(User, UserAdmin)
|
||||
|
||||
@admin.register(UserProfile)
|
||||
class UserProfileAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'name', 'email', 'phone', 'profile_picture')
|
||||
|
||||
admin.site.register(PasswordResetToken)
|
||||
6
accounts/apps.py
Normal file
6
accounts/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AccountsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'accounts'
|
||||
75
accounts/forms.py
Normal file
75
accounts/forms.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
from accounts.models import *
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# User Profile Form #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
class UserProfileForm(forms.ModelForm):
|
||||
role = forms.ChoiceField(choices=get_user_model().Role.choices, required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if 'instance' in kwargs:
|
||||
user = kwargs['instance'].user
|
||||
self.fields['role'].initial = user.role
|
||||
self.fields['role'].choices = get_user_model().Role.choices
|
||||
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
fields = ('profile_picture', 'name', 'slug', 'role', 'email', 'phone', 'address', 'city', 'state', 'country', 'zipcode', 'facebook', 'instagram', 'linkedin')
|
||||
widgets = {
|
||||
'profile_picture': forms.ClearableFileInput(attrs={'class': 'form-control'}),
|
||||
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'slug': forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
|
||||
'email': forms.EmailInput(attrs={'class': 'form-control'}),
|
||||
'phone': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'role': forms.Select(attrs={'class': 'form-select'}),
|
||||
'address': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'city': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'state': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'country': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'zipcode': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'facebook': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'instagram': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'linkedin': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
}
|
||||
def save(self, commit=True):
|
||||
instance = super().save(commit=False)
|
||||
if commit:
|
||||
user = instance.user
|
||||
user.role = self.cleaned_data['role']
|
||||
user.save()
|
||||
instance.save()
|
||||
return instance
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# User Creation Form #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
class CustomUserCreationForm(UserCreationForm):
|
||||
name = forms.CharField(max_length=255)
|
||||
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control'}))
|
||||
role = forms.ChoiceField(choices=[], widget=forms.Select(attrs={'class': 'form-select'}))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['role'].choices = get_user_model().Role.choices
|
||||
|
||||
class Meta:
|
||||
model = get_user_model()
|
||||
fields = ['name', 'username', 'password1', 'password2', 'email', 'role']
|
||||
widgets = {
|
||||
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'username': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'password1': forms.PasswordInput(attrs={'class': 'form-control'}),
|
||||
'password2': forms.PasswordInput(attrs={'class': 'form-control'}),
|
||||
}
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Password Form #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
class UserPasswordChangeForm(PasswordChangeForm):
|
||||
class Meta:
|
||||
model = User
|
||||
26
accounts/manager.py
Normal file
26
accounts/manager.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from django.contrib.auth.models import BaseUserManager
|
||||
|
||||
|
||||
class UserManager(BaseUserManager):
|
||||
def create_user(self, email, password=None, **extra_fields):
|
||||
if not email :
|
||||
raise ValueError('Users must have an email address')
|
||||
email = self.normalize_email(email)
|
||||
user = self.model(email=email,**extra_fields)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
return user
|
||||
|
||||
def create_superuser(self, email, password , **extra_fields):
|
||||
extra_fields.setdefault('is_superuser',True)
|
||||
extra_fields.setdefault('is_staff',True)
|
||||
extra_fields.setdefault('is_active',True)
|
||||
|
||||
if extra_fields.get('is_superuser') is not True:
|
||||
raise ValueError('Superuser must have is_superuser=True.')
|
||||
if extra_fields.get('is_staff') is not True:
|
||||
raise ValueError('Superuser must have is_staff=True.')
|
||||
if extra_fields.get('is_active') is not True:
|
||||
raise ValueError('Superuser must have is_active=True.')
|
||||
return self.create_user(email,password,**extra_fields)
|
||||
|
||||
65
accounts/migrations/0001_initial.py
Normal file
65
accounts/migrations/0001_initial.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# Generated by Django 4.2.4 on 2023-08-31 05:40
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('is_verified', models.BooleanField(default=False, verbose_name='Is Verified')),
|
||||
('role', models.CharField(blank=True, choices=[('Admin', 'Admin'), ('Editor', 'Editor')], max_length=255, null=True, verbose_name='Role')),
|
||||
('created', models.DateField(auto_now_add=True)),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'user',
|
||||
'verbose_name_plural': 'users',
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserProfile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('profile_picture', models.ImageField(blank=True, null=True, upload_to='user_pictures/')),
|
||||
('name', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('slug', models.SlugField(blank=True, max_length=255, null=True)),
|
||||
('email', models.EmailField(blank=True, max_length=255, null=True)),
|
||||
('phone', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('address', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('city', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('state', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('country', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('zipcode', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('facebook', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('instagram', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('linkedin', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
27
accounts/migrations/0002_passwordresettoken.py
Normal file
27
accounts/migrations/0002_passwordresettoken.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 4.2.4 on 2023-09-17 18:12
|
||||
|
||||
import datetime
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PasswordResetToken',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('expiration_time', models.DurationField(default=datetime.timedelta(seconds=3600))),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.4 on 2023-09-17 18:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0002_passwordresettoken'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='passwordresettoken',
|
||||
name='expiration_time',
|
||||
field=models.DateTimeField(),
|
||||
),
|
||||
]
|
||||
0
accounts/migrations/__init__.py
Normal file
0
accounts/migrations/__init__.py
Normal file
123
accounts/models.py
Normal file
123
accounts/models.py
Normal file
@@ -0,0 +1,123 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from accounts.manager import UserManager
|
||||
from django.contrib.auth.models import BaseUserManager
|
||||
from django.utils.text import slugify
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils import timezone
|
||||
import uuid
|
||||
|
||||
class User(AbstractUser):
|
||||
class Role(models.TextChoices):
|
||||
Admin = 'Admin',"Admin"
|
||||
Editor = 'Editor',"Editor"
|
||||
is_verified = models.BooleanField(default=False , verbose_name='Is Verified')
|
||||
role = models.CharField(max_length=255, verbose_name='Role' , choices=Role.choices, blank=True, null=True)
|
||||
created = models.DateField(auto_now_add=True)
|
||||
base_role = Role.Admin
|
||||
|
||||
objects = UserManager()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.pk and not self.role:
|
||||
self.role = self.base_role
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
||||
|
||||
# manager
|
||||
class CustomerUserManager(BaseUserManager):
|
||||
def get_queryset(self ,*args, **kwargs) :
|
||||
reasult = super().get_queryset(*args, **kwargs)
|
||||
return reasult.filter(role=User.Role.Editor)
|
||||
|
||||
|
||||
def create_user(self, email, password=None, **extra_fields):
|
||||
if not email :
|
||||
raise ValueError('Users must have an email address')
|
||||
email = self.normalize_email(email)
|
||||
user = self.model(email=email,**extra_fields)
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
# User Profile
|
||||
class UserProfile(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
profile_picture = models.ImageField(upload_to='user_pictures/', blank=True, null=True)
|
||||
name = models.CharField(max_length=255, blank=True, null=True)
|
||||
slug = models.SlugField(max_length=255, blank=True, null=True)
|
||||
email = models.EmailField(max_length=255, blank=True, null=True)
|
||||
phone = models.CharField(max_length=255, blank=True, null=True)
|
||||
address = models.CharField(max_length=255, blank=True, null=True)
|
||||
city = models.CharField(max_length=255, blank=True, null=True)
|
||||
state = models.CharField(max_length=255, blank=True, null=True)
|
||||
country = models.CharField(max_length=255, blank=True, null=True)
|
||||
zipcode = models.CharField(max_length=255, blank=True, null=True)
|
||||
facebook = models.CharField(max_length=500, blank=True, null=True)
|
||||
instagram = models.CharField(max_length=500, blank=True, null=True)
|
||||
linkedin = models.CharField(max_length=500, blank=True, null=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.pk:
|
||||
original_profile = UserProfile.objects.get(pk=self.pk)
|
||||
if original_profile.user.email != self.email:
|
||||
# Email has changed, update it in the associated User model
|
||||
original_profile.user.email = self.email
|
||||
original_profile.user.save()
|
||||
|
||||
self.slug = slugify(self.user.username)
|
||||
super(UserProfile, self).save(*args, **kwargs)
|
||||
|
||||
def getUserImage(self):
|
||||
image_url = ""
|
||||
if self.profile_picture:
|
||||
image_url = self.profile_picture.url
|
||||
else:
|
||||
image_url = "https://cdn-icons-png.flaticon.com/128/3135/3135715.png"
|
||||
return image_url
|
||||
|
||||
def __str__(self):
|
||||
return self.user.username
|
||||
|
||||
# Password reset token generate
|
||||
class PasswordResetToken(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
token = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
expiration_time = models.DateTimeField()
|
||||
|
||||
def __str__(self):
|
||||
return str(self.token)
|
||||
|
||||
def is_expired(self):
|
||||
now = timezone.now()
|
||||
return now > self.expiration_time
|
||||
# Signals
|
||||
@receiver(post_save, sender=User)
|
||||
def create_user_profile(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
UserProfile.objects.create(
|
||||
user=instance,
|
||||
email=instance.email,
|
||||
name=instance.username,
|
||||
slug=slugify(instance.username),
|
||||
)
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def save_user_profile(sender, instance, **kwargs):
|
||||
instance.userprofile.save()
|
||||
|
||||
# signals for User
|
||||
@receiver(post_save, sender=User)
|
||||
def create_customer_profile(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
UserProfile.objects.get_or_create(user=instance)
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def save_customer_profile(sender, instance, **kwargs):
|
||||
if hasattr(instance, 'userprofile'):
|
||||
instance.userprofile.save()
|
||||
31
accounts/templatetags/customtag.py
Normal file
31
accounts/templatetags/customtag.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from django import template
|
||||
from django.utils.timesince import timesince
|
||||
import random
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter
|
||||
def add_class(field, css_class):
|
||||
return field.as_widget(attrs={'class': css_class})
|
||||
|
||||
@register.filter
|
||||
def add_name(field, atrname):
|
||||
return field.as_widget(attrs={'name': atrname})
|
||||
|
||||
@register.filter
|
||||
def mul(value, arg):
|
||||
return value * arg
|
||||
|
||||
# Define a list of classes to choose from
|
||||
CLASS_CHOICES = ["primary", "danger", "warning", "success"]
|
||||
|
||||
@register.filter
|
||||
def random_class(value):
|
||||
# Choose a random class from the list
|
||||
return random.choice(CLASS_CHOICES)
|
||||
|
||||
@register.filter(name='attr')
|
||||
def attr(field, attribute):
|
||||
attr_name, attr_value = attribute.split('=')
|
||||
attrs = {attr_name: attr_value}
|
||||
return field.as_widget(attrs=attrs)
|
||||
3
accounts/tests.py
Normal file
3
accounts/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
16
accounts/urls.py
Normal file
16
accounts/urls.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.urls import path
|
||||
from accounts.views import *
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/users/user-list', usersList, name="userList"),
|
||||
path('admin/user/create', createUser, name="createUser"),
|
||||
path('admin/edit-profile/<int:id>', editUserProfile, name='editUserProfile'),
|
||||
path('admin/user/change-password/<int:id>', changePassword, name='changePassword'),
|
||||
path('admin/user/delete/<int:id>', deleteUser, name='deleteUser'),
|
||||
|
||||
path('forgot-password/', initiate_password_reset, name='initiate_password_reset'),
|
||||
path('reset_password/<uuid:token>/', reset_password, name='reset_password'),
|
||||
|
||||
path('login/', logIn, name='logIn'),
|
||||
path('logout/', LogOut, name='LogOut'),
|
||||
]
|
||||
31
accounts/utils.py
Normal file
31
accounts/utils.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# utils.py
|
||||
from django.conf import settings
|
||||
import uuid
|
||||
from django.core.mail import send_mail
|
||||
from django.utils import timezone
|
||||
from .models import PasswordResetToken
|
||||
from django.urls import reverse
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.html import strip_tags
|
||||
from settings.models import websiteSetting
|
||||
|
||||
|
||||
def generate_reset_token_and_send_email(user, request):
|
||||
token = uuid.uuid4() # Generate a UUID4 token
|
||||
expiration_time = timezone.now() + timezone.timedelta(hours=1)
|
||||
reset_token = PasswordResetToken.objects.create(user=user, token=token, expiration_time=expiration_time)
|
||||
|
||||
reset_link = request.build_absolute_uri(reverse('reset_password', args=[str(reset_token.token)]))
|
||||
|
||||
website_settings = websiteSetting.objects.first()
|
||||
subject = "Password Reset"
|
||||
html_message = render_to_string('authenticate/email/password_reset_email.html', {
|
||||
'user': user,
|
||||
'reset_link': reset_link,
|
||||
})
|
||||
plain_message = strip_tags(html_message)
|
||||
from_email = f'"{website_settings.name}" <{settings.EMAIL_HOST_USER}>'
|
||||
recipient_list = [user.email]
|
||||
|
||||
# Send the email with HTML content
|
||||
send_mail(subject, plain_message, from_email, recipient_list, html_message=html_message)
|
||||
223
accounts/views.py
Normal file
223
accounts/views.py
Normal file
@@ -0,0 +1,223 @@
|
||||
from django.shortcuts import render, redirect
|
||||
from accounts.models import *
|
||||
from django.http import Http404
|
||||
from accounts.forms import *
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import update_session_auth_hash
|
||||
from accounts.utils import *
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from core.decorators import *
|
||||
from django.conf import settings
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Admin User List #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
@login_required(login_url='logIn')
|
||||
@admin_role_required
|
||||
def usersList(request):
|
||||
users = UserProfile.objects.all()
|
||||
context = {
|
||||
'title': 'Users',
|
||||
'users': users,
|
||||
}
|
||||
return render(request, 'authenticate/user/users.html', context)
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Admin User Edit #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
@login_required(login_url='logIn')
|
||||
@admin_role_required
|
||||
def editUserProfile(request, id):
|
||||
try:
|
||||
profile = UserProfile.objects.get(id=id)
|
||||
user = profile.user
|
||||
except UserProfile.DoesNotExist:
|
||||
raise Http404("User profile does not exist")
|
||||
|
||||
if request.method == 'POST':
|
||||
form = UserProfileForm(request.POST, request.FILES, instance=profile)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, 'Profile updated successfully.')
|
||||
return redirect('editUserProfile', user.id)
|
||||
else:
|
||||
form = UserProfileForm(instance=profile)
|
||||
|
||||
context = {
|
||||
'title': 'Edit User Profile',
|
||||
'form': form,
|
||||
'profile': profile,
|
||||
'user': user,
|
||||
}
|
||||
return render(request, 'authenticate/user/edit.html', context)
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Admin User Create #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
@login_required(login_url='logIn')
|
||||
@admin_role_required
|
||||
def createUser(request):
|
||||
if request.method == 'POST':
|
||||
form = CustomUserCreationForm(request.POST)
|
||||
if form.is_valid():
|
||||
user = form.save(commit=False) # Prevent immediate save
|
||||
user.role = form.cleaned_data['role'] # Set role from form
|
||||
user.save() # Save User instance to DB
|
||||
|
||||
# Update or Create a profile for the user
|
||||
UserProfile.objects.update_or_create(
|
||||
user=user,
|
||||
defaults={
|
||||
'name': form.cleaned_data['name'],
|
||||
'email': form.cleaned_data['email']
|
||||
}
|
||||
)
|
||||
|
||||
return redirect('userList')
|
||||
else:
|
||||
print(form.errors)
|
||||
else:
|
||||
form = CustomUserCreationForm()
|
||||
|
||||
context = {
|
||||
'title': 'Create User',
|
||||
'form': form,
|
||||
}
|
||||
return render(request, 'authenticate/user/create.html', context)
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Admin User Password #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
@login_required(login_url='logIn')
|
||||
@admin_role_required
|
||||
def changePassword(request, id):
|
||||
|
||||
user = User.objects.get(id=id)
|
||||
profile = UserProfile.objects.get(user=user)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = UserPasswordChangeForm(user, request.POST)
|
||||
if form.is_valid():
|
||||
user = form.save()
|
||||
update_session_auth_hash(request, user)
|
||||
messages.success(request, 'Password changed successfully.')
|
||||
return redirect('changePassword', user.id)
|
||||
else:
|
||||
form = UserPasswordChangeForm(user)
|
||||
|
||||
context = {
|
||||
'title': 'Change Password',
|
||||
'form': form,
|
||||
'profile': profile,
|
||||
'user': user,
|
||||
}
|
||||
return render(request, 'authenticate/user/password.html', context)
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Admin Delete User #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
@login_required(login_url='logIn')
|
||||
@admin_role_required
|
||||
def deleteUser(request, id):
|
||||
try:
|
||||
user = User.objects.get(id=id)
|
||||
profile = UserProfile.objects.get(user=user)
|
||||
user.delete()
|
||||
profile.delete()
|
||||
except User.DoesNotExist:
|
||||
raise Http404("User does not exist")
|
||||
|
||||
return redirect('userList')
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Reset Password #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
def initiate_password_reset(request):
|
||||
if request.method == 'POST':
|
||||
username = request.POST.get('username')
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
generate_reset_token_and_send_email(user, request)
|
||||
messages.success(request, 'An email has sent!')
|
||||
return redirect('initiate_password_reset')
|
||||
except User.DoesNotExist:
|
||||
messages.warning(request, 'Invalid username!')
|
||||
return redirect('initiate_password_reset')
|
||||
context = {
|
||||
'title' : 'Forgot Password'
|
||||
}
|
||||
return render(request, 'authenticate/auth/forgotpassword.html', context)
|
||||
|
||||
def reset_password(request, token):
|
||||
try:
|
||||
password_reset_token = PasswordResetToken.objects.get(token=token)
|
||||
if password_reset_token.is_expired():
|
||||
messages.warning(request, 'The password reset token has expired. Please initiate the password reset process again.')
|
||||
return redirect('password_reset')
|
||||
|
||||
if request.method == 'POST':
|
||||
new_password1 = request.POST.get('new_password1')
|
||||
new_password2 = request.POST.get('new_password2')
|
||||
if new_password1 == new_password2:
|
||||
|
||||
user = password_reset_token.user
|
||||
user.set_password(new_password1)
|
||||
user.save()
|
||||
|
||||
update_session_auth_hash(request, user)
|
||||
|
||||
password_reset_token.delete()
|
||||
messages.success(request, 'Password reset successfully!')
|
||||
return redirect('/')
|
||||
else:
|
||||
messages.warning(request, 'Passwords did not match. Please try again.')
|
||||
return redirect('reset_password', token=token)
|
||||
context = {
|
||||
'title' : 'Reset Password'
|
||||
}
|
||||
return render(request, 'authenticate/auth/reset.html', context)
|
||||
except PasswordResetToken.DoesNotExist:
|
||||
messages.warning(request, 'Invalid token. Please ensure you have the correct link.')
|
||||
return redirect('initiate_password_reset')
|
||||
except Exception as e:
|
||||
messages.warning(request, f'An error occurred: {str(e)}')
|
||||
return redirect('/')
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# Login #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
def logIn(request):
|
||||
if not request.user.is_authenticated:
|
||||
if request.method == 'POST':
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('login[password]')
|
||||
user = authenticate(request, username=username, password=password)
|
||||
if user is not None:
|
||||
login(request, user)
|
||||
return redirect('adminHome')
|
||||
else:
|
||||
messages.warning(request, 'Invalid username or password!')
|
||||
return redirect('logIn')
|
||||
|
||||
else:
|
||||
demo_mode = True if 'core.middleware.middleware.DemoModeMiddleware' in settings.MIDDLEWARE else False
|
||||
context = {
|
||||
'title' : 'Log In',
|
||||
'demo_mode' : demo_mode
|
||||
}
|
||||
return render(request, 'authenticate/auth/login.html', context)
|
||||
else:
|
||||
return redirect('adminHome')
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# LogOut #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
@login_required(login_url='signIn')
|
||||
def LogOut(request):
|
||||
logout(request)
|
||||
messages.success(request, 'Logout successfully!')
|
||||
return redirect('logIn')
|
||||
|
||||
def error_404(request, exception):
|
||||
return render(request, 'error/404.html', status=404)
|
||||
Reference in New Issue
Block a user