diff --git a/Base_Master/__pycache__/settings.cpython-311.pyc b/Base_Master/__pycache__/settings.cpython-311.pyc index 1cf6a33..0f90d63 100644 Binary files a/Base_Master/__pycache__/settings.cpython-311.pyc and b/Base_Master/__pycache__/settings.cpython-311.pyc differ diff --git a/Base_Master/__pycache__/urls.cpython-311.pyc b/Base_Master/__pycache__/urls.cpython-311.pyc index 2ae8c49..2ca292d 100644 Binary files a/Base_Master/__pycache__/urls.cpython-311.pyc and b/Base_Master/__pycache__/urls.cpython-311.pyc differ diff --git a/Base_Master/settings.py b/Base_Master/settings.py index 555c49f..bed2d45 100644 --- a/Base_Master/settings.py +++ b/Base_Master/settings.py @@ -21,7 +21,7 @@ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-k6k-x^q$jjp*@bs#_7yw-!&cyn4g^byvr*lseiok=h=t#!)bw4' - +ENCRYPT_KEY = b'Py6zhVP-eFxkfq0kHUN0ZmIePwwaOeQ12ZmrFAVLbI8=' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True diff --git a/Base_Master/urls.py b/Base_Master/urls.py index 30ceda4..58192b4 100644 --- a/Base_Master/urls.py +++ b/Base_Master/urls.py @@ -9,4 +9,5 @@ path('home', views.home, name="home"), path('register/', views.signup_view, name="sign_up"), path('profile/', views.profile, name="profile"), + path('update//', views.update, name="update"), ] diff --git a/firstapp/__pycache__/encryption_util.cpython-311.pyc b/firstapp/__pycache__/encryption_util.cpython-311.pyc new file mode 100644 index 0000000..fad7009 Binary files /dev/null and b/firstapp/__pycache__/encryption_util.cpython-311.pyc differ diff --git a/firstapp/__pycache__/forms.cpython-311.pyc b/firstapp/__pycache__/forms.cpython-311.pyc index 3e28034..3815602 100644 Binary files a/firstapp/__pycache__/forms.cpython-311.pyc and b/firstapp/__pycache__/forms.cpython-311.pyc differ diff --git a/firstapp/__pycache__/views.cpython-311.pyc b/firstapp/__pycache__/views.cpython-311.pyc index 71155ee..1218914 100644 Binary files a/firstapp/__pycache__/views.cpython-311.pyc and b/firstapp/__pycache__/views.cpython-311.pyc differ diff --git a/firstapp/encryption_util.py b/firstapp/encryption_util.py new file mode 100644 index 0000000..b767c80 --- /dev/null +++ b/firstapp/encryption_util.py @@ -0,0 +1,38 @@ +from cryptography.fernet import Fernet +import base64 +import logging +import traceback +from django.conf import settings + +#this is your "password/ENCRYPT_KEY". keep it in settings.py file +key = Fernet.generate_key() + +def encrypt(txt): + try: + # convert integer etc to string first + txt = str(txt) + # get the key from settings + cipher_suite = Fernet(settings.ENCRYPT_KEY) # key should be byte + # #input should be byte, so convert the text to byte + encrypted_text = cipher_suite.encrypt(txt.encode('ascii')) + # encode to urlsafe base64 format + encrypted_text = base64.urlsafe_b64encode(encrypted_text).decode("ascii") + return encrypted_text + except Exception as e: + # log the error if any + print(e) + logging.getLogger("error_logger").error(traceback.format_exc()) + return None + + +def decrypt(txt): + try: + # base64 decode + txt = base64.urlsafe_b64decode(txt) + cipher_suite = Fernet(settings.ENCRYPT_KEY) + decoded_text = cipher_suite.decrypt(txt).decode("ascii") + return decoded_text + except Exception as e: + # log the error + logging.getLogger("error_logger").error(traceback.format_exc()) + return None \ No newline at end of file diff --git a/firstapp/forms.py b/firstapp/forms.py index 54c9ec4..c78e357 100644 --- a/firstapp/forms.py +++ b/firstapp/forms.py @@ -22,6 +22,10 @@ def clean_email(self): return email class profile_edit(forms.ModelForm): + first_name = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Enter First name'}), required=True) + last_name = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Enter last name'}), required=True) + email = forms.EmailField(widget=forms.EmailInput(attrs={'class':'form-control', 'placeholder': 'Enter Email address'}), required=True) + username = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Enter username'}), required=True) class Meta: model = User - fields=['username','email','first_name','last_name', "is_superuser"] \ No newline at end of file + fields=['username','email','first_name','last_name',] \ No newline at end of file diff --git a/firstapp/views.py b/firstapp/views.py index 63f611b..e6f2442 100644 --- a/firstapp/views.py +++ b/firstapp/views.py @@ -1,7 +1,10 @@ from django.shortcuts import render, redirect from django.contrib import messages from django.contrib.auth import login, authenticate +from django.contrib.auth.models import User +from django.contrib.auth.decorators import login_required # Create your views here. + def home(request): if request.user.is_authenticated: return render(request, 'home.html') @@ -26,4 +29,47 @@ def signup_view(request): def profile(request): - return render(request, 'profile.html') \ No newline at end of file + if request.user.is_authenticated: + lst = User.objects.filter(username=request.user).values('id') + l=[] + for i in lst: + i['encrypt_key']=encrypt(i['id']) + i['id']=i['id'] + l.append(i) + return render(request, 'profile.html', {'lst':l}) + else: + messages.error(request, 'Please Provide the credentials to Login to your account.') + return redirect("login") + + +from django.shortcuts import redirect, render, get_object_or_404 +from firstapp.encryption_util import * +@login_required +def update(request,id): + id=decrypt(id) + + # dictionary for initial data with + # field names as keys + context ={} + + # fetch the object related to passed id + obj = get_object_or_404(User, id = id) + if request.user == obj: + + # pass the object as instance in form + form = profile_edit(request.POST or None, instance = obj) + + # save the data from the form and + # redirect to detail_view + if form.is_valid(): + form.save() + messages.success(request, 'Profile updated successfully!') + return redirect('profile') + + # add form dictionary to context + context["form"] = form + + return render(request, "edit_profile.html", context) + else: + messages.error(request,"You cannot access other user profile") + return redirect("profile") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 044d355..0eb476e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,9 @@ asgiref==3.5.2 +cffi==1.15.1 +cryptography==39.0.0 Django==4.0.4 django-crispy-forms==1.14.0 django-jazzmin==2.5.0 -sqlparse==0.4.2 -tzdata==2022.1 -asgiref==3.5.2 -Django==4.0.4 -django-crispy-forms==1.14.0 -django-jazzmin==2.5.0 +pycparser==2.21 sqlparse==0.4.2 tzdata==2022.1 diff --git a/static/login_styling/assets/css/style.css b/static/login_styling/assets/css/style.css index 6da1e13..12f0d3f 100644 --- a/static/login_styling/assets/css/style.css +++ b/static/login_styling/assets/css/style.css @@ -1,19 +1,3 @@ -/*-----------------------------------*\ - #style.css -\*-----------------------------------*/ - -/** - * copyright 2022 codewithsadee - */ - - - - - -/*-----------------------------------*\ - #CUSTOM PROPERTY -\*-----------------------------------*/ - :root { /** @@ -1048,3 +1032,294 @@ body { } + + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: var(--bs-body-color); + background-color: transparent; + background-clip: padding-box; + border: 1px solid #dee2e6; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0.375rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none; + } +} +.form-control[type="file"] { + overflow: hidden; +} +.form-control[type="file"]:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control:focus { + color: #212529; + background-color: #fff; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-control::-webkit-date-and-time-value { + height: 1.5em; +} +.form-control::-webkit-datetime-edit { + display: block; + padding: 0; +} +.form-control::-moz-placeholder { + color: rgba(173, 181, 189, 0.75); + opacity: 1; +} +.form-control::placeholder { + color: rgba(173, 181, 189, 0.75); + opacity: 1; +} +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: var(--bs-secondary-bg); +} +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: var(--bs-secondary-bg); +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); +} +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-top: var(--bs-gutter-y); +} +.col { + flex: 1 0 0%; +} + +.form-label { + margin-bottom: 0.5rem; +} +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} +/* The alert message box */ +.alert-success { + padding: 20px; + background-color: #0abb04c9; /* green */ + color: white; + margin-bottom: 15px; + opacity: 1; + transition: opacity 0.6s; +} + +.alert-danger { + padding: 20px; + background-color: #ff0000; /* green */ + color: white; + margin-bottom: 15px; + opacity: 1; + transition: opacity 0.6s; +} + +/* The close button */ +.closebtn { + margin-left: 15px; + color: white; + font-weight: bold; + float: right; + font-size: 22px; + line-height: 20px; + cursor: pointer; + transition: 0.3s; +} + +/* When moving the mouse over the close button */ +.closebtn:hover { + color: black; +} + +.btn { + --bs-btn-padding-x: 0.75rem; + --bs-btn-padding-y: 0.375rem; + --bs-btn-font-family: ; + --bs-btn-font-size: 1rem; + --bs-btn-font-weight: 400; + --bs-btn-line-height: 1.5; + --bs-btn-color: #212529; + --bs-btn-bg: transparent; + --bs-btn-border-width: var(--bs-border-width); + --bs-btn-border-color: transparent; + --bs-btn-border-radius: 0.375rem; + --bs-btn-hover-border-color: transparent; + --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), + 0 1px 1px rgba(0, 0, 0, 0.075); + --bs-btn-disabled-opacity: 0.65; + --bs-btn-focus-box-shadow: 0 0 0 0.25rem + rgba(var(--bs-btn-focus-shadow-rgb), 0.5); + display: inline-block; + padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x); + font-family: var(--bs-btn-font-family); + font-size: var(--bs-btn-font-size); + font-weight: var(--bs-btn-font-weight); + line-height: var(--bs-btn-line-height); + color: var(--bs-btn-color); + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + border: var(--bs-btn-border-width) solid var(--bs-btn-border-color); + border-radius: var(--bs-btn-border-radius); + background-color: var(--bs-btn-bg); + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, + border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); +} +.btn-check + .btn:hover { + color: var(--bs-btn-color); + background-color: var(--bs-btn-bg); + border-color: var(--bs-btn-border-color); +} +.btn:focus-visible { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-focus-box-shadow); +} +.btn-check:focus-visible + .btn { + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-focus-box-shadow); +} +.btn-check:checked + .btn, +.btn.active, +.btn.show, +.btn:first-child:active, +:not(.btn-check) + .btn:active { + color: var(--bs-btn-active-color); + background-color: var(--bs-btn-active-bg); + border-color: var(--bs-btn-active-border-color); +} +.btn-check:checked + .btn:focus-visible, +.btn.active:focus-visible, +.btn.show:focus-visible, +.btn:first-child:active:focus-visible, +:not(.btn-check) + .btn:active:focus-visible { + box-shadow: var(--bs-btn-focus-box-shadow); +} +.btn.disabled, +.btn:disabled, +fieldset:disabled .btn { + color: var(--bs-btn-disabled-color); + pointer-events: none; + background-color: var(--bs-btn-disabled-bg); + border-color: var(--bs-btn-disabled-border-color); + opacity: var(--bs-btn-disabled-opacity); +} +.btn-outline-primary { + --bs-btn-color: #0d6efd; + --bs-btn-border-color: #0d6efd; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #0d6efd; + --bs-btn-hover-border-color: #0d6efd; + --bs-btn-focus-shadow-rgb: 13, 110, 253; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #0d6efd; + --bs-btn-active-border-color: #0d6efd; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #0d6efd; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #0d6efd; + --bs-gradient: none; +} +.btn-outline-danger { + --bs-btn-color: #dc3545; + --bs-btn-border-color: #dc3545; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #dc3545; + --bs-btn-hover-border-color: #dc3545; + --bs-btn-focus-shadow-rgb: 220, 53, 69; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #dc3545; + --bs-btn-active-border-color: #dc3545; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #dc3545; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #dc3545; + --bs-gradient: none; +} +.btn-outline-success { + --bs-btn-color: #038045; + --bs-btn-border-color: #198754; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #198754; + --bs-btn-hover-border-color: #198754; + --bs-btn-focus-shadow-rgb: 25, 135, 84; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #198754; + --bs-btn-active-border-color: #198754; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #198754; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #198754; + --bs-gradient: none; +} +.btn-outline-info { + --bs-btn-color: #0dcaf0; + --bs-btn-border-color: #0dcaf0; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #0dcaf0; + --bs-btn-hover-border-color: #0dcaf0; + --bs-btn-focus-shadow-rgb: 13, 202, 240; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #0dcaf0; + --bs-btn-active-border-color: #0dcaf0; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #0dcaf0; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #0dcaf0; + --bs-gradient: none; +} +.d-grid { + display: grid !important; +} +.gap-3 { + gap: 1rem !important; +} +@media (min-width: 576px) { + .d-md-block { + display: block !important; + } +} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 1ac670d..b126e1c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -34,7 +34,6 @@ -
diff --git a/templates/edit_profile.html b/templates/edit_profile.html new file mode 100644 index 0000000..6a47826 --- /dev/null +++ b/templates/edit_profile.html @@ -0,0 +1,79 @@ +{% extends 'base.html' %} +{% block pagetitle %}Profile{% endblock %} +{% load static %} +{% block content %} +
+
+

Update Profile

+
+
+
+ {% csrf_token %} +
+ +
+ {{user.get_full_name}} +
+ +
+
+
+ + {{form.first_name}} +
+
+ + {{form.last_name}} +
+
+

+ +

+ {% if user.is_superuser %} +

+ + {% elif user.is_staff %} + + {% else %} + + {% endif %} +

+
+ +
+ +
    + + +
+ +
+
+ + + +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/profile.html b/templates/profile.html index f630c2b..c94138e 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -5,6 +5,14 @@

Profile Section

+ {% if messages %} + {% for message in messages %} +
+ × + {{message}} +
+ {% endfor %} + {% endif %}
@@ -17,8 +25,9 @@

Profile Section