diff --git a/README.md b/README.md index 1a2d25e..7bda3bd 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ production néccessite **une installation de Debian Bullseye**. $ sudo apt install nginx git gettext uwsgi uwsgi-plugin-python3 python3-venv \ python3-certbot-nginx python3-django python3-django-crispy-forms \ python3-django-taggit python3-pil python3-exifread python3-django-allauth \ - python3-psycopg2 + python3-psycopg2 python3-docutils ``` 2. **Clonage du dépot dans `/var/www/photos/photo21`** @@ -122,6 +122,7 @@ production néccessite **une installation de Debian Bullseye**. $ sudo -u www-data ./venv/bin/python ./manage.py collectstatic $ sudo -u www-data ./venv/bin/python ./manage.py check $ sudo -u www-data ./venv/bin/python ./manage.py migrate + $ sudo -u www-data ./venv/bin/python ./manage.py loaddata initial $ sudo ./venv/bin/python ./manage.py compilemessages ``` diff --git a/photo21/fixtures/initial.json b/photo21/fixtures/initial.json new file mode 100644 index 0000000..6a3f0a0 --- /dev/null +++ b/photo21/fixtures/initial.json @@ -0,0 +1,58 @@ +[ + { + "model": "sites.site", + "pk": 1, + "fields": { + "domain": "photos.crans.org", + "name": "Serveur photos" + } + }, + { + "model": "photologue.photosize", + "pk": 1, + "fields": { + "name": "admin_thumbnail", + "width": 100, + "height": 75, + "quality": 70, + "upscale": false, + "crop": true, + "pre_cache": true, + "increment_count": false, + "effect": null, + "watermark": null + } + }, + { + "model": "photologue.photosize", + "pk": 2, + "fields": { + "name": "thumbnail", + "width": 250, + "height": 180, + "quality": 70, + "upscale": false, + "crop": true, + "pre_cache": true, + "increment_count": false, + "effect": null, + "watermark": null + } + }, + { + "model": "photologue.photosize", + "pk": 3, + "fields": { + "name": "display", + "width": 1980, + "height": 0, + "quality": 70, + "upscale": false, + "crop": false, + "pre_cache": true, + "increment_count": true, + "effect": null, + "watermark": null + } + } +] \ No newline at end of file diff --git a/photo21/hashers.py b/photo21/hashers.py new file mode 100644 index 0000000..0c3305a --- /dev/null +++ b/photo21/hashers.py @@ -0,0 +1,48 @@ +import hashlib +import base64 +from collections import OrderedDict + +from django.utils.crypto import constant_time_compare +from django.utils.encoding import force_bytes +from django.utils.translation import gettext_noop as _ +from django.contrib.auth.hashers import mask_hash, BasePasswordHasher + + +class SHA512PasswordHasher(BasePasswordHasher): + """ + The SHA512 password hashing algorithm + + It is used to migrate passwords from old Symfony2 photos server. + https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php + """ + algorithm = "sha512" + + def encode(self, password, iteration, salt): + assert password is not None + assert salt and '$' not in salt + salted = force_bytes(password + "{" + salt + "}") + digest = hashlib.sha512(salted).digest() + # "stretch" hash + for _i in range(1, int(iteration)): + digest = hashlib.sha512(digest + salted).digest() + digest = base64.b64encode(digest).decode() + encoded = "%s$%s$%s$%s" % (self.algorithm, iteration, salt, digest) + return encoded[:128] + + def verify(self, password, encoded): + algorithm, iteration, salt, hash = encoded.split('$', 3) + assert algorithm == self.algorithm + encoded_2 = self.encode(password, iteration, salt) + return constant_time_compare(encoded, encoded_2) + + def safe_summary(self, encoded): + algorithm, iteration, salt, hash = encoded.split('$', 3) + assert algorithm == self.algorithm + return OrderedDict([ + (_('algorithm'), algorithm), + (_('salt'), mask_hash(salt, show=2)), + (_('hash'), mask_hash(hash)), + ]) + + def harden_runtime(self, password, encoded): + pass diff --git a/photo21/settings.py b/photo21/settings.py index f2da6ab..f5aaaa0 100644 --- a/photo21/settings.py +++ b/photo21/settings.py @@ -29,6 +29,8 @@ SECRET_KEY = 'CHANGE_ME' DEBUG = True ALLOWED_HOSTS = [ + "127.0.0.1", + "localhost", "photos.crans.org", "photos-dev.crans.org", ] @@ -127,6 +129,11 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +PASSWORD_HASHERS = [ + 'django.contrib.auth.hashers.PBKDF2PasswordHasher', + 'photo21.hashers.SHA512PasswordHasher', +] + # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ @@ -167,7 +174,7 @@ MEDIA_URL = '/media/' LOCALE_PATHS = [os.path.join(BASE_DIR, 'photo21/locale')] -FIXTURE_DIRS = [os.path.join(BASE_DIR, 'note_kfet/fixtures')] +FIXTURE_DIRS = [os.path.join(BASE_DIR, 'photo21/fixtures')] # Email settings if DEBUG: diff --git a/photologue_custom/admin.py b/photologue_custom/admin.py index cfd8ddf..2c0aca0 100644 --- a/photologue_custom/admin.py +++ b/photologue_custom/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin from photologue.admin import GalleryAdmin as GalleryAdminDefault from photologue.admin import PhotoAdmin as PhotoAdminDefault -from photologue.models import Gallery, Photo +from photologue.models import Gallery, Photo, PhotoEffect, PhotoSize, Watermark from .models import GalleryExtended, PhotoExtended @@ -34,5 +34,8 @@ class PhotoAdmin(PhotoAdminDefault): admin.site.unregister(Gallery) admin.site.unregister(Photo) +admin.site.unregister(PhotoEffect) +admin.site.unregister(PhotoSize) +admin.site.unregister(Watermark) admin.site.register(Gallery, GalleryAdmin) admin.site.register(Photo, PhotoAdmin) diff --git a/photologue_custom/migrations/0002_auto_20211011_1956.py b/photologue_custom/migrations/0002_auto_20211011_1956.py new file mode 100644 index 0000000..d03ea2c --- /dev/null +++ b/photologue_custom/migrations/0002_auto_20211011_1956.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.24 on 2021-10-11 19:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('photologue_custom', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='galleryextended', + name='date_end', + field=models.DateField(blank=True, null=True, verbose_name='end date'), + ), + migrations.AddField( + model_name='galleryextended', + name='date_start', + field=models.DateField(blank=True, null=True, verbose_name='start date'), + ), + ] diff --git a/photologue_custom/models.py b/photologue_custom/models.py index 76d7f86..76be399 100644 --- a/photologue_custom/models.py +++ b/photologue_custom/models.py @@ -10,7 +10,7 @@ class GalleryExtended(models.Model): gallery = models.OneToOneField( Gallery, related_name='extended', - on_delete='cascade', + on_delete=models.CASCADE, ) # Add tags @@ -41,7 +41,7 @@ class PhotoExtended(models.Model): photo = models.OneToOneField( Photo, related_name='extented', - on_delete='cascade' + on_delete=models.CASCADE, ) # Add a owner field to PhotoExtended diff --git a/photologue_custom/templates/photologue/gallery_archive.html b/photologue_custom/templates/photologue/gallery_archive.html index d68fcee..babfaeb 100644 --- a/photologue_custom/templates/photologue/gallery_archive.html +++ b/photologue_custom/templates/photologue/gallery_archive.html @@ -22,8 +22,8 @@
{% if latest %}
- {% for gallery in latest %} -
+ {% for gallery in latest|slice:":32" %} +
{% include "photologue/includes/gallery_sample.html" %}
{% endfor %} diff --git a/photologue_custom/templates/photologue/gallery_archive_year.html b/photologue_custom/templates/photologue/gallery_archive_year.html index 63db8b0..84f535c 100644 --- a/photologue_custom/templates/photologue/gallery_archive_year.html +++ b/photologue_custom/templates/photologue/gallery_archive_year.html @@ -17,7 +17,7 @@ {% if object_list %}
{% for gallery in object_list %} -
+
{% include "photologue/includes/gallery_sample.html" %}
{% endfor %} diff --git a/photologue_custom/templates/photologue/gallery_detail.html b/photologue_custom/templates/photologue/gallery_detail.html index d5545f4..03415cb 100644 --- a/photologue_custom/templates/photologue/gallery_detail.html +++ b/photologue_custom/templates/photologue/gallery_detail.html @@ -22,7 +22,7 @@ {% block content %}

{{ gallery.title }}

-

{% trans "Published" %} {{ gallery.date_added }}

+

{% trans "Published" %} {{ gallery.date_added|date }}

{% if gallery.extended.tags.all %}

Tags : {% for tag in gallery.extended.tags.all %} @@ -34,7 +34,7 @@

diff --git a/photologue_custom/templates/photologue/includes/gallery_sample.html b/photologue_custom/templates/photologue/includes/gallery_sample.html index 8dcc05c..34d53a8 100644 --- a/photologue_custom/templates/photologue/includes/gallery_sample.html +++ b/photologue_custom/templates/photologue/includes/gallery_sample.html @@ -6,7 +6,7 @@ {% endfor %}
{{ gallery.title }}
-

{% trans "Published" %} {{ gallery.date_added }}

+

{% trans "Published" %} {{ gallery.date_added|date }}

{% if gallery.description %}

{{ gallery.description|safe }}

{% endif %}
diff --git a/tox.ini b/tox.ini index 30d8c12..333bfcb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,5 @@ [tox] envlist = - # Debian Buster Python - py37-django22 - # Ubuntu 20.04 Python py38-django22