Added basic user authentication.

This commit is contained in:
2023-08-23 17:45:39 -04:00
parent 511acab59c
commit bac5437e7e
8 changed files with 95 additions and 13 deletions

View File

@@ -104,6 +104,10 @@ AUTH_PASSWORD_VALIDATORS = [
}, },
] ]
# Authentication.
LOGIN_REDIRECT_URL = '/gallery/'
LOGOUT_REDIRECT_URL = 'login'
LOGIN_URL = 'login'
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/ # https://docs.djangoproject.com/en/4.2/topics/i18n/

View File

@@ -21,6 +21,9 @@ from django.conf.urls.static import static
from django.urls import (path, from django.urls import (path,
include) include)
from django.contrib.auth import views
# Project imports.
from viewer.views import index from viewer.views import index
########################################################################################### ###########################################################################################
@@ -31,8 +34,13 @@ urlpatterns = [
# Index. # Index.
path('', index, name = 'home'), path('', index, name = 'home'),
# Auth views.
path("login/", views.LoginView.as_view(), name = 'login'),
path("logout/", views.LogoutView.as_view(), name = 'logout'),
# Add invoices app urls. # Add invoices app urls.
path('gallery/', include('viewer.urls')), path('gallery/', include('viewer.urls')),
] + static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)\ ] + static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)\
+ static('imgs/', document_root = settings.GALLERY_ROOT)\ + static('imgs/', document_root = settings.GALLERY_ROOT)\
+ static('thumbs/', document_root = settings.THUMBNAILS_ROOT) + static('thumbs/', document_root = settings.THUMBNAILS_ROOT)

View File

@@ -4,4 +4,8 @@ A basic pure HTML+CSS gallery viewer in the vein of [PiGallery 2](https://bpatri
## User authentication. ## User authentication.
Currently there is no authentication at all because I don't need it. This is meant to be installed in a server with HTTP basic auth enabled if needed. To login a user should be manually created by running the following commands in the Django shell, substituting the user's name, email and password as needed:
from django.contrib.auth.models import User
user = User.objects.create_user('<USERNAME>', '<EMAIL>', '<PASSWORD>')
user.save()

View File

@@ -44,6 +44,10 @@ body {
width: 100%; width: 100%;
} }
.pd {
padding: 10%;
}
/**************************************************************************** /****************************************************************************
* Content. * * Content. *
****************************************************************************/ ****************************************************************************/
@@ -83,7 +87,7 @@ body {
margin-left: 2em; margin-left: 2em;
} }
.search-btn { .clear-btn {
border: none; border: none;
background-color: #00000000; background-color: #00000000;
} }
@@ -92,6 +96,10 @@ body {
height: 2.5em; height: 2.5em;
} }
.float-right {
float: right;
}
/**************************************************************************** /****************************************************************************
* Grid. * * Grid. *
****************************************************************************/ ****************************************************************************/

BIN
viewer/static/imgs/boot.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -43,11 +43,21 @@
<!-- Page links. --> <!-- Page links. -->
{% if num_pages > 1 %} {% if num_pages > 1 %}
<td> <td>
<div class="mauto"> <div class="mauto mr-2">
{% for page in pages %}<a href="./?page={{page}}{%if search %}&{{search}}{% endif %}">{{page}}</a>{% if not forloop.last %}<span> </span>{% endif %}{% endfor %} {% for page in pages %}<a href="./?page={{page}}{%if search %}&{{search}}{% endif %}">{{page}}</a>{% if not forloop.last %}<span> </span>{% endif %}{% endfor %}
</div> </div>
</td> </td>
{% endif %} {% endif %}
<!-- Logout button. -->
<td>
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button type="submit" class="clear-btn">
<img src="{% static 'imgs/boot.png' %}" class="small-nav-icon">
</button>
</form>
</td>
</tr> </tr>
</table> </table>
@@ -70,7 +80,7 @@
<!-- Search submit. --> <!-- Search submit. -->
<td> <td>
<button type="submit" class="search-btn"> <button type="submit" class="clear-btn">
<img src="{% static 'imgs/find.png' %}" class="small-nav-icon"> <img src="{% static 'imgs/find.png' %}" class="small-nav-icon">
</button> </button>
</td> </td>

View File

@@ -0,0 +1,42 @@
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height" />
<title>
NibasaViewer login
</title>
<link href="{% static 'css/styles.css' %}" rel="stylesheet">
</head>
<body class="background">
<div class="fc mauto pd">
<form method="post" action="{% url 'login' %}" class="fc">
{% csrf_token %}
<table>
<tr>
<td>
{{ form.username.label_tag }}
</td>
<td>
{{ form.username }}
</td>
</tr>
<tr>
<td>
{{ form.password.label_tag }}
</td>
<td>
{{ form.password }}
</td>
</tr>
</table>
<input type="submit" value="login" class="float-right">
<input type="hidden" name="next" value="{{ next }}">
</form>
</div>
</body>
</html>

View File

@@ -9,6 +9,10 @@ import filetype
from django.http import HttpResponseNotFound from django.http import HttpResponseNotFound
from django.conf import settings from django.conf import settings
from django.utils.http import urlencode from django.utils.http import urlencode
from django.contrib.auth.decorators import login_required
from django.contrib.auth import (authenticate,
login,
logout)
from django.shortcuts import (render, from django.shortcuts import (render,
redirect) redirect)
@@ -24,12 +28,9 @@ ROWS_PER_PAGE = 4
IMAGES_PER_PAGE = CELLS_PER_ROW * ROWS_PER_PAGE IMAGES_PER_PAGE = CELLS_PER_ROW * ROWS_PER_PAGE
########################################################################################### ###########################################################################################
# View functions. # # Helper functions. #
########################################################################################### ###########################################################################################
def index(request):
return redirect('gallery_view_root')
def do_recursive_search(start_path, query): def do_recursive_search(start_path, query):
""" """
Gets all images and sub-directories inside the start_path whose name matches the given query, Gets all images and sub-directories inside the start_path whose name matches the given query,
@@ -56,6 +57,11 @@ def do_recursive_search(start_path, query):
# View functions. # # View functions. #
########################################################################################### ###########################################################################################
@login_required
def index(request):
return redirect('gallery_view_root')
@login_required
def gallery_view(request, path = None): def gallery_view(request, path = None):
""" """
Shows a list of subdirectories and image files inside the given path. Shows a list of subdirectories and image files inside the given path.