Skip to content

Commit

Permalink
private file field and private files directory (#814)
Browse files Browse the repository at this point in the history
  • Loading branch information
NC-jsAhonen authored Jan 20, 2025
1 parent 1021eb9 commit a4fd0f3
Show file tree
Hide file tree
Showing 15 changed files with 208 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
/.idea/
/.tox/
/media/
/private_files/
/static/
/venv/
/laske_export_files/
Expand Down
26 changes: 26 additions & 0 deletions forms/migrations/0027_private_filefield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 4.2.16 on 2025-01-14 07:42

import django.core.files.storage
from django.db import migrations
import forms.models.form
import utils.models.fields


class Migration(migrations.Migration):

dependencies = [
("forms", "0026_alter_answer_user_alter_attachment_user"),
]

operations = [
migrations.AlterField(
model_name="attachment",
name="attachment",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=forms.models.form.get_attachment_file_upload_to,
),
),
]
3 changes: 2 additions & 1 deletion forms/models/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from helsinki_gdpr.models import SerializableMixin

from users.models import User
from utils.models.fields import PrivateFileField

from ..enums import ApplicantType, FormState, SectionType
from ..utils import clone_object, generate_unique_identifier
Expand Down Expand Up @@ -209,7 +210,7 @@ def get_attachment_file_upload_to(instance, filename):

class Attachment(SerializableMixin, models.Model):
name = models.CharField(max_length=255)
attachment = models.FileField(upload_to=get_attachment_file_upload_to)
attachment = PrivateFileField(upload_to=get_attachment_file_upload_to)
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Time created"))
path = models.TextField(null=True, blank=True)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ def check_is_directory_writable(self, directory):

def handle(self, *args, **options):
destination_path = (
Path(settings.MEDIA_ROOT) / CollectionLetterTemplate.file.field.upload_to
Path(settings.PRIVATE_FILES_LOCATION)
/ CollectionLetterTemplate.file.field.upload_to
)
if not self.check_is_directory_writable(destination_path):
raise CommandError(
Expand Down Expand Up @@ -123,7 +124,9 @@ def handle(self, *args, **options):
name=name, file=str(destination_filename)
)

destination_path = Path(settings.MEDIA_ROOT) / destination_filename
destination_path = (
Path(settings.PRIVATE_FILES_LOCATION) / destination_filename
)

self.stdout.write(
' Copying "{}" to "{}"'.format(source_filename, destination_path)
Expand Down
96 changes: 96 additions & 0 deletions leasing/migrations/0089_private_filefield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Generated by Django 4.2.16 on 2025-01-14 07:42

import django.core.files.storage
from django.db import migrations
import leasing.models.debt_collection
import leasing.models.infill_development_compensation
import leasing.models.inspection
import leasing.models.land_area
import leasing.models.land_use_agreement
import utils.models.fields


class Migration(migrations.Migration):

dependencies = [
(
"leasing",
"0088_remove_rent_old_dwellings_in_housing_companies_price_index_type_and_more",
),
]

operations = [
migrations.AlterField(
model_name="collectioncourtdecision",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=leasing.models.debt_collection.get_collection_court_decision_file_upload_to,
verbose_name="File",
),
),
migrations.AlterField(
model_name="collectionletter",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=leasing.models.debt_collection.get_collection_letter_file_upload_to,
verbose_name="File",
),
),
migrations.AlterField(
model_name="collectionlettertemplate",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to="collection_letter_templates/",
verbose_name="File",
),
),
migrations.AlterField(
model_name="infilldevelopmentcompensationattachment",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=leasing.models.infill_development_compensation.get_attachment_file_upload_to,
),
),
migrations.AlterField(
model_name="inspectionattachment",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=leasing.models.inspection.get_inspection_attachment_file_upload_to,
),
),
migrations.AlterField(
model_name="landuseagreementattachment",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=leasing.models.land_use_agreement.get_attachment_file_upload_to,
),
),
migrations.AlterField(
model_name="leaseareaattachment",
name="file",
field=utils.models.fields.PrivateFileField(
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=leasing.models.land_area.get_attachment_file_upload_to,
),
),
]
7 changes: 4 additions & 3 deletions leasing/models/debt_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from field_permissions.registry import field_permissions
from leasing.models.mixins import TimeStampedSafeDeleteModel
from users.models import User
from utils.models.fields import PrivateFileField


def get_collection_letter_file_upload_to(instance, filename):
Expand All @@ -28,7 +29,7 @@ class CollectionLetter(TimeStampedSafeDeleteModel):
)

# In Finnish: Tiedosto
file = models.FileField(
file = PrivateFileField(
upload_to=get_collection_letter_file_upload_to,
verbose_name=_("File"),
blank=False,
Expand Down Expand Up @@ -59,7 +60,7 @@ class CollectionLetterTemplate(TimeStampedSafeDeleteModel):
"""

name = models.CharField(verbose_name=_("Name"), max_length=255)
file = models.FileField(
file = PrivateFileField(
upload_to="collection_letter_templates/",
verbose_name=_("File"),
blank=False,
Expand Down Expand Up @@ -126,7 +127,7 @@ class CollectionCourtDecision(TimeStampedSafeDeleteModel):
)

# In Finnish: Tiedosto
file = models.FileField(
file = PrivateFileField(
upload_to=get_collection_court_decision_file_upload_to,
verbose_name=_("File"),
blank=False,
Expand Down
3 changes: 2 additions & 1 deletion leasing/models/infill_development_compensation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from leasing.models.decision import DecisionMaker
from leasing.models.lease import IntendedUse
from users.models import User
from utils.models.fields import PrivateFileField

from .mixins import TimeStampedSafeDeleteModel

Expand Down Expand Up @@ -297,7 +298,7 @@ class InfillDevelopmentCompensationAttachment(TimeStampedSafeDeleteModel):
)

# In Finnish: Tiedosto
file = models.FileField(
file = PrivateFileField(
upload_to=get_attachment_file_upload_to, blank=False, null=False
)

Expand Down
3 changes: 2 additions & 1 deletion leasing/models/inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from field_permissions.registry import field_permissions
from leasing.models.mixins import TimeStampedSafeDeleteModel
from users.models import User
from utils.models.fields import PrivateFileField


class Inspection(models.Model):
Expand Down Expand Up @@ -59,7 +60,7 @@ class InspectionAttachment(TimeStampedSafeDeleteModel):
)

# In Finnish: Tiedosto
file = models.FileField(
file = PrivateFileField(
upload_to=get_inspection_attachment_file_upload_to, blank=False, null=False
)

Expand Down
3 changes: 2 additions & 1 deletion leasing/models/land_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from leasing.models.lease import Lease
from leasing.models.utils import normalize_identifier
from users.models import User
from utils.models.fields import PrivateFileField

from .mixins import (
ArchivableModel,
Expand Down Expand Up @@ -335,7 +336,7 @@ class LeaseAreaAttachment(TimeStampedSafeDeleteModel):
type = EnumField(LeaseAreaAttachmentType, verbose_name=_("Type"), max_length=30)

# In Finnish: Tiedosto
file = models.FileField(
file = PrivateFileField(
upload_to=get_attachment_file_upload_to, blank=False, null=False
)

Expand Down
3 changes: 2 additions & 1 deletion leasing/models/land_use_agreement.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from leasing.models.lease import District, Municipality
from leasing.utils import calculate_increase_with_360_day_calendar
from users.models import User
from utils.models.fields import PrivateFileField

from .mixins import NameModel, TimeStampedSafeDeleteModel

Expand Down Expand Up @@ -334,7 +335,7 @@ class LandUseAgreementAttachment(TimeStampedSafeDeleteModel):
)

# In Finnish: Tiedosto
file = models.FileField(
file = PrivateFileField(
upload_to=get_attachment_file_upload_to, blank=False, null=False
)

Expand Down
2 changes: 2 additions & 0 deletions mvj/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ def get_git_revision_hash():

MEDIA_ROOT = project_root("media")
STATIC_ROOT = project_root("static")
PRIVATE_FILES_LOCATION = project_root("private_files")

MEDIA_URL = "/media/"
STATIC_URL = "/static/"

Expand Down
40 changes: 40 additions & 0 deletions plotsearch/migrations/0042_private_filefield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Django 4.2.16 on 2025-01-14 07:42

import django.core.files.storage
from django.db import migrations
import plotsearch.models.plot_search
import utils.models.fields


class Migration(migrations.Migration):

dependencies = [
("plotsearch", "0041_alter_areasearch_options"),
]

operations = [
migrations.AlterField(
model_name="areasearchattachment",
name="attachment",
field=utils.models.fields.PrivateFileField(
blank=True,
null=True,
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=plotsearch.models.plot_search.get_area_search_attachment_upload_to,
),
),
migrations.AlterField(
model_name="meetingmemo",
name="meeting_memo",
field=utils.models.fields.PrivateFileField(
blank=True,
null=True,
storage=django.core.files.storage.FileSystemStorage(
base_url="/attachments/", location="attachments"
),
upload_to=plotsearch.models.plot_search.get_meeting_memo_file_upload_to,
),
),
]
9 changes: 6 additions & 3 deletions plotsearch/models/plot_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
)
from plotsearch.utils import map_intended_use_to_lessor
from users.models import User
from utils.models.fields import PrivateFileField


class PlotSearchType(NameModel):
Expand Down Expand Up @@ -404,7 +405,7 @@ def get_meeting_memo_file_upload_to(instance, filename):
class MeetingMemo(models.Model):
# In Finnish: Kokousmuistio
name = models.CharField(max_length=255)
meeting_memo = models.FileField(
meeting_memo = PrivateFileField(
upload_to=get_meeting_memo_file_upload_to, null=True, blank=True
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Time created"))
Expand Down Expand Up @@ -625,8 +626,10 @@ def get_area_search_attachment_upload_to(instance, filename):


class AreaSearchAttachment(SerializableMixin, NameModel):
attachment = models.FileField(
upload_to=get_area_search_attachment_upload_to, null=True, blank=True
attachment = PrivateFileField(
upload_to=get_area_search_attachment_upload_to,
null=True,
blank=True,
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Time created"))

Expand Down
17 changes: 17 additions & 0 deletions utils/models/fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Any

from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.db import models


class PrivateFileSystemStorage(FileSystemStorage):
def __init__(self) -> None:
# base_url is not needed, but it defaults to MEDIA_URL if not explicitly set
super().__init__(location=settings.PRIVATE_FILES_LOCATION, base_url=None)


class PrivateFileField(models.FileField):
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.storage = PrivateFileSystemStorage()
2 changes: 1 addition & 1 deletion utils/viewsets/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def download(self, request, pk=None, file_field: str | None = None):
filename = getattr(obj, file_field).name
else:
filename = obj.file.name
filepath = "/".join([settings.MEDIA_ROOT, filename])
filepath = "/".join([settings.PRIVATE_FILES_LOCATION, filename])
response = FileResponse(open(filepath, "rb"), as_attachment=True)

return response
Expand Down

0 comments on commit a4fd0f3

Please sign in to comment.