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

@@ -6,11 +6,15 @@ from math import ceil
import filetype import filetype
# Django imports. # Django imports.
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.shortcuts import (render, from django.contrib.auth.decorators import login_required
redirect) from django.contrib.auth import (authenticate,
login,
logout)
from django.shortcuts import (render,
redirect)
# Project imports. # Project imports.
from .utils import make_thumbnail from .utils import make_thumbnail
@@ -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.