Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
library-app-django
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ilham Maulana
library-app-django
Commits
9a5d21c0
Commit
9a5d21c0
authored
Jul 16, 2024
by
Ilham Maulana
💻
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: librarian authentication
parent
cb812483
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
282 additions
and
7 deletions
+282
-7
settings.py
config/settings.py
+2
-0
urls.py
config/urls.py
+17
-0
profile.html
dashboard/templates/profile.html
+1
-1
forms.py
users/forms.py
+88
-0
middleware.py
users/middleware.py
+18
-0
forgot_password.html
users/templates/librarians/forgot_password.html
+23
-0
login.html
users/templates/librarians/login.html
+28
-0
sign_up.html
users/templates/librarians/sign_up.html
+32
-0
views.py
users/views.py
+73
-6
No files found.
config/settings.py
View file @
9a5d21c0
...
...
@@ -71,6 +71,8 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware"
,
"django.contrib.messages.middleware.MessageMiddleware"
,
"django.middleware.clickjacking.XFrameOptionsMiddleware"
,
# local
"users.middleware.AuthMiddleware"
,
]
ROOT_URLCONF
=
"config.urls"
...
...
config/urls.py
View file @
9a5d21c0
...
...
@@ -19,7 +19,15 @@ from django.contrib import admin
from
django.urls
import
path
,
include
from
django.conf
import
settings
from
django.conf.urls.static
import
static
from
django.contrib.auth.views
import
LogoutView
from
dashboard.views
import
UpcomingLoanView
,
OverduedLoanView
from
users.views
import
(
LibrarianLoginView
,
LibrarianLogoutView
,
LibrarianSignUpView
,
LibrarianResetPassword
,
)
urlpatterns
=
[
# local
...
...
@@ -30,6 +38,15 @@ urlpatterns = [
path
(
"book-loans/"
,
include
(
"loans.urls"
)),
path
(
"upcoming-loans/"
,
UpcomingLoanView
.
as_view
(),
name
=
"upcoming_loans"
),
path
(
"overdued-loans/"
,
OverduedLoanView
.
as_view
(),
name
=
"overdued_loans"
),
# auth
path
(
"auth/login/"
,
LibrarianLoginView
.
as_view
(),
name
=
"librarian_login"
),
path
(
"auth/logout/"
,
LibrarianLogoutView
.
as_view
(),
name
=
"librarian_logout"
),
path
(
"auth/sign-up/"
,
LibrarianSignUpView
.
as_view
(),
name
=
"librarian_logout"
),
path
(
"auth/forgot-password/"
,
LibrarianResetPassword
.
as_view
(),
name
=
"reset_password"
,
),
# api
path
(
"api/v1/"
,
include
(
"api.urls"
),
name
=
"API_V1"
),
# 3rd party
...
...
dashboard/templates/profile.html
View file @
9a5d21c0
...
...
@@ -14,7 +14,7 @@
>
<a
class=
"w-100 btn btn-outline-primary border-white text-white text-start"
href=
"/
auth/logout/{{ user.id }}
/"
href=
"/
logout
/"
><i
class=
"bi bi-box-arrow-left"
></i>
logout
</a
>
</div>
...
...
users/forms.py
View file @
9a5d21c0
from
django
import
forms
from
users.models
import
User
from
django.contrib.auth
import
password_validation
from
django.contrib.auth.forms
import
(
UserCreationForm
,
AuthenticationForm
,
PasswordResetForm
,
UsernameField
,
)
class
UserForm
(
forms
.
ModelForm
):
...
...
@@ -42,3 +49,84 @@ class UserForm(forms.ModelForm):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
UserForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
fields
[
"password"
]
.
required
=
False
class
SignUpForm
(
UserCreationForm
):
password1
=
forms
.
CharField
(
label
=
(
"Password"
),
strip
=
False
,
widget
=
forms
.
PasswordInput
(
attrs
=
{
"placeholder"
:
"Password"
,
"autocomplete"
:
"new-password"
,
"class"
:
"form-control my-4"
,
}
),
help_text
=
password_validation
.
password_validators_help_text_html
(),
)
password2
=
forms
.
CharField
(
label
=
(
"Password confirmation"
),
widget
=
forms
.
PasswordInput
(
attrs
=
{
"placeholder"
:
"Password confirmation"
,
"autocomplete"
:
"new-password"
,
"class"
:
"form-control my-4"
,
}
),
strip
=
False
,
help_text
=
(
"Enter the same password as before, for verification."
),
)
class
Meta
:
model
=
User
fields
=
[
"username"
,
"password1"
,
"password2"
]
widgets
=
{
"username"
:
forms
.
TextInput
(
attrs
=
{
"placeholder"
:
"Username"
,
"class"
:
"form-control my-4"
,
}
),
}
class
LoginForm
(
AuthenticationForm
):
username
=
UsernameField
(
widget
=
forms
.
TextInput
(
attrs
=
{
"placeholder"
:
"Username"
,
"autofocus"
:
True
,
"class"
:
"form-control"
,
}
)
)
password
=
forms
.
CharField
(
label
=
(
"Password"
),
strip
=
False
,
widget
=
forms
.
PasswordInput
(
attrs
=
{
"placeholder"
:
"Password"
,
"autocomplete"
:
"current-password"
,
"class"
:
"form-control"
,
}
),
)
class
Meta
:
model
=
User
fields
=
[
"username"
,
"password"
]
class
ForgotPasswordForm
(
PasswordResetForm
):
email
=
forms
.
EmailField
(
label
=
(
"Email"
),
max_length
=
254
,
widget
=
forms
.
EmailInput
(
attrs
=
{
"placeholder"
:
"Email"
,
"autocomplete"
:
"email"
,
"class"
:
"form-control"
,
}
),
)
users/middleware.py
0 → 100644
View file @
9a5d21c0
from
django.utils.deprecation
import
MiddlewareMixin
from
django.http
import
HttpResponseRedirect
class
AuthMiddleware
(
MiddlewareMixin
):
def
__init__
(
self
,
get_response
):
self
.
get_response
=
get_response
def
__call__
(
self
,
request
):
response
=
self
.
get_response
(
request
)
if
not
request
.
user
.
is_authenticated
and
request
.
path
.
startswith
(
"/dashboard/"
):
return
HttpResponseRedirect
(
"/auth/login"
)
elif
request
.
user
.
is_authenticated
and
request
.
path
.
startswith
(
"/auth/"
):
return
HttpResponseRedirect
(
"/dashboard/"
)
else
:
return
response
users/templates/librarians/forgot_password.html
0 → 100644
View file @
9a5d21c0
{% extends "base.html" %} {% block content %}
<main
style=
"min-height: 100vh"
class=
"w-100 h-100 bg-body-secondary d-flex justify-content-center align-items-center"
>
<form
method=
"POST"
class=
"card gap-3 d-flex w-25 p-4 rounded-4 shadow"
>
<h1
class=
"h3 text-center mb-4"
>
Forgot Password
</h1>
{% csrf_token %}
{{ form }}
<button
type=
"submit"
id=
"submit_reset_password"
class=
"btn btn-primary my-2 rounded-5"
>
Reset Password
</button>
<a
href=
"/auth/login/"
class=
"text-center my-2"
>
Back to Login
</a>
</form>
</main>
{% endblock content %}
\ No newline at end of file
users/templates/librarians/login.html
0 → 100644
View file @
9a5d21c0
{% extends "base.html" %} {% block content %}
<main
style=
"min-height: 100vh"
class=
"w-100 h-100 bg-body-secondary d-flex justify-content-center align-items-center"
>
<form
method=
"POST"
class=
"card gap-3 d-flex w-25 p-4 rounded-4 shadow"
>
<h1
class=
"h3 text-center mb-4"
>
Login
</h1>
{% csrf_token %}
{{ form }}
<button
type=
"submit"
id=
"submit-login"
class=
"btn btn-primary my-2 rounded-5"
>
Login
</button>
<div
class=
"d-flex flex-column align-items-center"
>
<p
class=
"my-2"
>
Don't have an account?
<a
href=
"/auth/sign-up"
>
Sign Up
</a>
</p>
<a
href=
"/auth/forgot-password/"
class=
"my-2"
>
Forgot password
</a>
</div>
</form>
</main>
{% endblock content %}
\ No newline at end of file
users/templates/librarians/sign_up.html
0 → 100644
View file @
9a5d21c0
{% extends "base.html" %} {% block content %}
<main
style=
"min-height: 100vh"
class=
"w-100 h-100 bg-body-secondary d-flex justify-content-center align-items-center"
>
<form
method=
"POST"
class=
"card gap-2 w-25 p-4 rounded-4 shadow"
>
<h1
class=
"h3 text-center mb-4"
>
Sign Up
</h1>
{% csrf_token %}
{{ form }}
<button
type=
"submit"
id=
"submit-sign-up"
class=
"btn btn-primary my-2 rounded-5"
>
Sign Up
</button>
<div
class=
"d-flex flex-column align-items-center"
>
{% if error_message %}
<p
class=
"alert alert-warning small"
role=
"alert"
>
<i
class=
"bi bi-exclamation-circle"
></i>
{{ error_message }}
</p>
{% endif %}
<p
class=
"my-2"
>
Already have an account?
<a
href=
"/auth/login"
>
Login
</a>
</p>
</div>
</form>
</main>
{% endblock content %}
\ No newline at end of file
users/views.py
View file @
9a5d21c0
from
django.db.models
import
Q
from
django.views
import
generic
from
django.contrib.auth
import
logout
from
django.http
import
HttpResponseRedirect
from
django.contrib.auth.views
import
LoginView
,
PasswordResetView
from
users.models
import
Librarian
,
Member
from
users.forms
import
UserForm
,
User
from
users.forms
import
UserForm
,
User
,
LoginForm
,
SignUpForm
,
ForgotPasswordForm
class
UserListView
(
generic
.
ListView
):
...
...
@@ -100,12 +104,12 @@ class LibrarianCreateView(UserCreateView):
class
LibrarianUpdateView
(
UserUpdateView
):
model
=
Librarian
success_url
=
"/
dashboard
/librarians"
success_url
=
"/
users
/librarians"
class
LibrarianDeleteView
(
UserDeleteView
):
model
=
Librarian
success_url
=
"/
dashboard
/librarians"
success_url
=
"/
users
/librarians"
class
MemberListView
(
UserListView
):
...
...
@@ -116,7 +120,7 @@ class MemberListView(UserListView):
class
MemberCreateView
(
UserCreateView
):
model
=
User
success_url
=
"/
dashboard
/members/"
success_url
=
"/
users
/members/"
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
form
=
self
.
get_form
()
...
...
@@ -131,9 +135,72 @@ class MemberCreateView(UserCreateView):
class
MemberUpdateView
(
UserUpdateView
):
model
=
Member
success_url
=
"/
dashboard
/members"
success_url
=
"/
users
/members"
class
MemberDeleteView
(
UserDeleteView
):
model
=
Member
success_url
=
"/dashboard/members"
success_url
=
"/users/members"
class
LibrarianLoginView
(
LoginView
):
form_class
=
LoginForm
template_name
=
"librarians/login.html"
redirect_authenticated_user
=
"/dashboard/"
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
form
=
self
.
get_form
()
context
=
self
.
get_context_data
()
if
form
.
is_valid
():
username
=
form
.
data
.
get
(
"username"
)
user
=
User
.
objects
.
get
(
username
=
username
)
if
not
user
.
is_staff
:
context
[
"error_message"
]
=
"Access Denie, account is not staff"
return
self
.
form_invalid
(
form
)
return
self
.
form_valid
(
form
)
else
:
return
self
.
form_invalid
(
form
)
class
LibrarianLogoutView
(
generic
.
TemplateView
):
success_url
=
"/auth/login/"
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
context
=
self
.
get_context_data
(
**
kwargs
)
if
request
.
user
.
is_authenticated
:
logout
(
request
)
return
HttpResponseRedirect
(
self
.
success_url
)
return
self
.
render_to_response
(
context
)
class
LibrarianSignUpView
(
generic
.
FormView
):
form_class
=
SignUpForm
template_name
=
"librarians/sign_up.html"
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
form
=
self
.
get_form
()
if
form
.
is_valid
:
username
=
form
.
data
.
get
(
"username"
)
email
=
form
.
data
.
get
(
"email"
)
password
=
form
.
data
.
get
(
"password"
)
user
=
User
.
objects
.
create_user
(
username
=
username
,
email
=
email
,
password
=
password
)
Librarian
.
objects
.
create
(
user
=
user
)
return
self
.
form_valid
(
form
)
else
:
return
self
.
form_invalid
(
form
)
class
LibrarianResetPassword
(
PasswordResetView
):
form_class
=
ForgotPasswordForm
template_name
=
"librarians/forgot_password.html"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment