From 489bb5bbfdb5357ae174564101132979f2a31f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Canek=20Pel=C3=A1ez=20Vald=C3=A9s?= Date: Wed, 17 Nov 2021 01:57:02 -0600 Subject: [PATCH] Access control infrastructure. We can have private photos and albums; the photos themselves can still be accessed throught Apache, but we are working on it. --- fotos/models.py | 96 +++++++++++++-- fotos/templates/album.html | 79 +++--------- fotos/templates/base.html | 3 +- fotos/templatetags/galeria.py | 21 +++- fotos/urls.py | 2 + fotos/util.py | 10 +- fotos/views.py | 152 +++++++++++++++++++++-- galeria/settings.sample.py | 41 ++++--- locale/es_MX/LC_MESSAGES/django.po | 187 +++++++++++++++++------------ static/admin.css | 4 +- static/galeria.js | 2 + static/style.css | 6 +- 12 files changed, 417 insertions(+), 186 deletions(-) diff --git a/fotos/models.py b/fotos/models.py index 14a8425..ac3317b 100644 --- a/fotos/models.py +++ b/fotos/models.py @@ -11,7 +11,8 @@ from galeria.settings import PREFIX, STATIC_PATH_PREFIX, UPLOAD_TMP_DIR, \ from babel.dates import format_datetime from datetime import datetime, timezone, timedelta -from fotos.util import get_image_metadata, get_month_name, normalize +from fotos.util import get_image_metadata, get_month_name, get_year_name, \ + normalize def float2degrees(d): i = math.floor(d) @@ -60,10 +61,12 @@ class Album(models.Model): .filter(the_parent=self, slug=slug) \ .order_by('first_timestamp').first() - def get_tree(self): + def get_tree(self, auth=False): tree = {} subalbums = self.get_subalbums() for subalbum in subalbums: + if not auth and subalbum.private: + continue tree[subalbum.slug] = { 'album': subalbum, 'label': subalbum.get_day_range(), 'tree': subalbum.get_tree() } @@ -118,6 +121,54 @@ class Album(models.Model): if not self.the_parent.the_parent.the_parent: self._highlight_event() + def has_public_photos(self): + photos = self.get_photos() + if photos: + for photo in photos: + if not photo.private: + return True + else: + for subalbum in self.get_subalbums(): + if subalbum.has_public_photos(): + return True + return False + + def make_private(self): + if self.private: + return + self.private = True + self.save() + photos = self.get_photos() + if photos: + for photo in photos: + if not photo.private: + photo.private = True + photo.save() + else: + for subalbum in self.get_subalbums(): + if not subalbum.private: + subalbum.make_private() + if self.the_parent and not self.the_parent.has_public_photos(): + self.the_parent.make_private() + + def make_public(self): + if not self.private: + return + if self.the_parent and self.the_parent.private: + return + self.private = False + self.save() + photos = self.get_photos() + if photos: + for photo in photos: + if photo.private: + photo.private = False + photo.save() + else: + for subalbum in self.get_subalbums(): + if subalbum.private: + subalbum.make_public() + @transaction.atomic def do_delete(self): if not self.the_parent: @@ -370,6 +421,14 @@ class Album(models.Model): def get_years(klass): return Album.objects.filter(the_parent=None).order_by('first_timestamp') + @classmethod + def has_public_years(klass): + for year in Album.objects.filter(the_parent=None)\ + .order_by('first_timestamp'): + if not year.private: + return True + return False + @classmethod def get_year(klass, year): return Album.objects.filter(the_parent=None, slug=year).first() @@ -386,12 +445,13 @@ class Album(models.Model): @classmethod def get_random_photo(klass, blacklist=None): - if not blacklist: - return Photo.objects.all().order_by('?').first() + photo = Photo.objects.filter(private=False).order_by('?').first() + if not photo or not blacklist: + return photo terms = [ t.lower() for t in blacklist.split(',') ] blacklisted = True while blacklisted: - photo = Photo.objects.all().order_by('?').first() + photo = Photo.objects.filter(private=False).order_by('?').first() blacklisted = False for term in terms: if photo.matches(term): @@ -461,10 +521,12 @@ class Album(models.Model): year.reset() @classmethod - def full_tree(klass): + def full_tree(klass, auth=False): tree = {} years = Album.objects.filter(the_parent=None).order_by('first_timestamp') for year in years: + if not auth and year.private: + continue tree[year.slug] = { 'album': year, 'label': year.get_day_range(), 'tree': year.get_tree() } @@ -649,6 +711,22 @@ class Photo(models.Model): ea.the_photo = self ea.save() + def make_private(self): + if self.private: + return + self.private = True + self.save() + if not self.the_album.has_public_photos(): + self.the_album.make_private() + + def make_public(self): + if not self.private: + return + if self.the_album.private: + return + self.private = False + self.save() + def __str__(self): s = '%s (%s): %04d/%02d/%02d %02d:%02d:%02d' % \ (self.title, self.basename, @@ -720,13 +798,13 @@ class Photo(models.Model): @classmethod def _get_photo_album(klass, metadata): ts = metadata['timestamp'] - tz = timezone(timedelta(hours=metadata['time_offset'])) + offset = metadata['time_offset'] sy = '%04d' % ts.year sm = '%02d' % ts.month year = Album.objects.filter(the_parent=None, slug=sy).first() if not year: year = Album(the_parent = None, - name = _('Year %(year)s') % { 'year': sy }, + name = get_year_name(sy), slug = sy, first_timestamp = ts, last_timestamp = ts, @@ -736,7 +814,7 @@ class Photo(models.Model): month = Album.objects.filter(the_parent=year, slug=sm).first() if not month: month = Album(the_parent = year, - name = get_month_name(ts, tz, capitalize=True), + name = get_month_name(ts, offset, True), slug = sm, first_timestamp = ts, last_timestamp = ts, diff --git a/fotos/templates/album.html b/fotos/templates/album.html index 526fb1c..6e904d9 100644 --- a/fotos/templates/album.html +++ b/fotos/templates/album.html @@ -3,67 +3,24 @@ {% load static %} {% load galeria %} {% block content %} -
- {% if photos %} - {% for photo in photos %} -
-
-
- - {{photo.title}} - -
-
- {{photo.title}} -
-
-
- {% endfor %} - {% elif results %} - {% for result in results %} -
-
-
- - {{result.title}} - -
-
- {{result.title}} -
-
-
- {% endfor %} - {% elif albums %} - {% for album in albums %} - {% if album.the_photo %} -
-
-
- - {{album.name}} - -
-
- {{album.name}} -
-
-
- {% endif %} - {% endfor %} - {% else %} - +
+ {% for photo in photos %} + {% if not photo.private or user.is_authenticated %} + {% include "photo-preview.html" %} {% endif %} + {% endfor %} + {% for photo in results %} + {% if not photo.private or user.is_authenticated %} + {% include "photo-preview.html" %} + {% endif %} + {% endfor %} + {% for album in albums %} + {% if not album.private or user.is_authenticated %} + {% include "album-preview.html" %} + {% endif %} + {% endfor %} + +
{% endblock %} diff --git a/fotos/templates/base.html b/fotos/templates/base.html index 9bbe64c..bce4de4 100644 --- a/fotos/templates/base.html +++ b/fotos/templates/base.html @@ -134,7 +134,8 @@

-

{{page_title}}

+

{{page_title}} +  

{% if summary %}
{{summary}}
{% endif %} {% if search %}