Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/hide play files #753

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ dmypy.json
# Media and Static Django
/media
/staticfiles
/protected_media

# Logs Django
/logs
Expand Down
17 changes: 17 additions & 0 deletions apps/core/services/file_access.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Сервис контроля доступа к файлам для приложени django-private-storage."""

from pathlib import Path

from django.conf import settings
from private_storage.models import PrivateFile

from apps.library.models.play import Play


def has_download_permission(private_file: PrivateFile) -> bool:
user = private_file.request.user
if user.is_authenticated and user.is_staff:
return True

relative_path = Path(private_file.full_path).relative_to(settings.PRIVATE_STORAGE_ROOT)
return Play.objects.filter(url_download=relative_path, published=True).exists()
38 changes: 38 additions & 0 deletions apps/library/migrations/0044_alter_play_url_download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 3.2.23 on 2024-01-26 13:30

import apps.content_pages.utilities
import django.core.validators
from django.conf import settings
from django.db import migrations
import private_storage.fields
import private_storage.storage.files
from shutil import copytree, move

REGULAR_MEDIA = settings.MEDIA_ROOT / "plays"
PROTECTED_MEDIA = settings.PRIVATE_STORAGE_ROOT / "plays"


def move_to_protected_media(apps, schema_editor):
if REGULAR_MEDIA.exists():
copytree(REGULAR_MEDIA, PROTECTED_MEDIA, copy_function=move, dirs_exist_ok=True)


def move_from_protected_media(apps, schema_editor):
if PROTECTED_MEDIA.exists():
copytree(PROTECTED_MEDIA, REGULAR_MEDIA, copy_function=move, dirs_exist_ok=True)


class Migration(migrations.Migration):

dependencies = [
('library', '0043_alter_socialnetworklink_name'),
]

operations = [
migrations.AlterField(
model_name='play',
name='url_download',
field=private_storage.fields.PrivateFileField(blank=True, help_text="Файл пьесы должен быть в одном из следующих форматов: ('doc', 'docx', 'txt', 'odt', 'pdf')", max_length=200, null=True, storage=private_storage.storage.files.PrivateFileSystemStorage(), upload_to=apps.content_pages.utilities.path_by_media_and_class_name, validators=[django.core.validators.FileExtensionValidator(('doc', 'docx', 'txt', 'odt', 'pdf'))], verbose_name='Текст пьесы'),
),
migrations.RunPython(move_to_protected_media, move_from_protected_media),
]
3 changes: 2 additions & 1 deletion apps/library/models/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.db import models
from django.db.models import UniqueConstraint
from django.utils.translation import gettext_lazy as _
from private_storage.fields import PrivateFileField

from apps.content_pages.utilities import path_by_media_and_class_name
from apps.core.mixins import FileCleanUpMixin
Expand Down Expand Up @@ -65,7 +66,7 @@ class Play(FileCleanUpMixin, BaseModel):
blank=True,
null=True,
)
url_download = models.FileField(
url_download = PrivateFileField(
validators=(FileExtensionValidator(ALLOWED_FORMATS_FILE_FOR_PLAY),),
max_length=200,
blank=True,
Expand Down
7 changes: 7 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"anymail",
"easy_thumbnails",
"apps.filer.apps.FilerCustomConfig",
"private_storage",
]
LOCAL_APPS = [
"apps.users",
Expand Down Expand Up @@ -385,6 +386,12 @@
LOCALE_PATHS = [Path(STATIC_ROOT) / "core" / "locale", ]


# Private storage settings
PRIVATE_STORAGE_ROOT = ROOT_DIR / "protected_media"
PRIVATE_STORAGE_AUTH_FUNCTION = "apps.core.services.file_access.has_download_permission"
PRIVATE_STORAGE_SERVER = "nginx"
PRIVATE_STORAGE_INTERNAL_URL = "/private-redirect/"

# APP SETTINGS
AFISHA_REGISTRATION_OPENS_HOURS_BEFORE = 12
POSTFIX_MAIL_DOMAIN = os.environ.get("POSTFIX_MAIL_DOMAIN")
Expand Down
5 changes: 5 additions & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import private_storage.urls
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
Expand Down Expand Up @@ -79,3 +80,7 @@
view=include("filer.urls"),
),
] + static(MEDIA_URL, document_root=MEDIA_ROOT)

urlpatterns += [
path("private-media/", include(private_storage.urls)),
]
2 changes: 2 additions & 0 deletions infra_deploy/prod/lubimovka_backend_prod_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ services:
volumes:
- static_value_prod:/code/staticfiles/
- ./media:/code/media/
- ./protected_media:/code/protected_media/
- ./logs/backend_logs/:/code/logs/
depends_on:
- postgres
Expand All @@ -32,6 +33,7 @@ services:
volumes:
- static_value_prod:/code/staticfiles/
- ./media:/code/media/
- ./protected_media:/code/protected_media/
- ./logs/backend_logs/:/code/logs/
command: >
sh -c "
Expand Down
1 change: 1 addition & 0 deletions infra_deploy/prod/lubimovka_frontend_prod_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ services:
- ./logs/swag_logs/:/config/log/
- static_value_prod:/config/prod/static/
- ./media:/config/prod/media/
- ./protected_media:/config/prod/protected_media/
ports:
- 443:443
- 80:80
Expand Down
7 changes: 6 additions & 1 deletion infra_deploy/prod/swag/swag_nginx_prod.conf
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ server {
# proxy_http_version 1.1;
# proxy_set_header Connection "";
}
location ~^/(api|admin|files) {
location ~^/(api|admin|files|private-media) {
include /config/nginx/proxy.conf;
set $upstream_app backend_prod;
set $upstream_port 8000;
Expand All @@ -53,6 +53,11 @@ server {
add_header Content-disposition "attachment; filename=$1";
}

location /private-redirect/ {
internal;
alias /config/prod/protected_media/;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А почему тут конфиг в пути?

в докере указывается /code/protected_media/, не знаю пересекаются эти пути или нет

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для swag задано

- ./protected_media:/config/prod/protected_media/

Для backend задано

- ./protected_media:/code/protected_media/

Таким образом в одна и так же папка на хосте сопоставлена двум папкам:
в контейнере backend это /code/protected_media/, а в контейнере swag это /config/prod/protected_media/.

Это конфиг Nginx, поэтому тут путь указывается так, как он выглядит из контейнера Nginx (Swag).

}

location ~^/(media|static) {
set $width $arg_w;
if ($arg_w = ''){
Expand Down
2 changes: 2 additions & 0 deletions infra_deploy/stage/lubimovka_backend_stage_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ services:
volumes:
- static_value_stage:/code/staticfiles/
- ./media:/code/media/
- ./protected_media:/code/protected_media/
- ./logs/backend_logs/:/code/logs/
depends_on:
- postgres
Expand All @@ -34,6 +35,7 @@ services:
volumes:
- static_value_stage:/code/staticfiles/
- ./media:/code/media/
- ./protected_media:/code/protected_media/
- ./logs/backend_logs/:/code/logs/
command: >
sh -c "
Expand Down
1 change: 1 addition & 0 deletions infra_deploy/stage/lubimovka_frontend_stage_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ services:
- ./logs/swag_logs/:/config/log/
- static_value_stage:/config/stage/static/
- ./media:/config/stage/media/
- ./protected_media:/config/stage/protected_media/
ports:
- 443:443
- 80:80
Expand Down
8 changes: 7 additions & 1 deletion infra_deploy/stage/swag/swag_nginx_stage.conf
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ server {
# proxy_http_version 1.1;
# proxy_set_header Connection "";
}
location ~^/(api|admin|files) {
location ~^/(api|admin|files|private-media) {
include /config/nginx/proxy.conf;
set $upstream_app backend;
set $upstream_port 8000;
Expand All @@ -55,6 +55,12 @@ server {
add_header Content-disposition "attachment; filename=$1";
}


location /private-redirect/ {
internal;
alias /config/stage/protected_media/;
}

location ~^/(media|static) {
set $width $arg_w;
if ($arg_w = ''){
Expand Down
2 changes: 2 additions & 0 deletions infra_deploy/test/lubimovka_backend_test_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ services:
volumes:
- static_value_test:/code/staticfiles/
- ./media:/code/media/
- ./protected_media:/code/protected_media/
- ./logs/backend_logs/:/code/logs/
depends_on:
- postgres
Expand All @@ -34,6 +35,7 @@ services:
volumes:
- static_value_test:/code/staticfiles/
- ./media:/code/media/
- ./protected_media:/code/protected_media/
- ./logs/backend_logs/:/code/logs/
command: >
sh -c "sleep 5; python manage.py migrate &&
Expand Down
1 change: 1 addition & 0 deletions infra_deploy/test/lubimovka_frontend_test_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ services:
- ./logs/nginx_logs/:/var/log/nginx/
- static_value_test:/config/test/static/
- ./media:/config/test/media/
- ./protected_media:/config/test/protected_media/
ports:
- 8080:80
restart: unless-stopped
Expand Down
7 changes: 6 additions & 1 deletion infra_deploy/test/nginx/nginx_test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ server {
# proxy_http_version 1.1;
# proxy_set_header Connection "";
}
location ~^/(api|admin|files|__debug__) {
location ~^/(api|admin|files|private-media|__debug__) {
#include proxy_params;
proxy_set_header Host $proxy_host;
resolver 127.0.0.11 valid=20s;
Expand All @@ -50,6 +50,11 @@ server {
root /config/test/;
}

location /private-redirect/ {
internal;
alias /config/test/protected_media/;
}

}


Expand Down
13 changes: 12 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ sqlparse = "^0.5.0"
easy-thumbnails = "^2.8.5"
idna = "^3.7"
black = "^24.4.0"
django-private-storage = "^3.1.1"

[tool.poetry.dev-dependencies]
pre-commit = "^2.15.0"
Expand Down
1 change: 1 addition & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ django-filter==21.1 ; python_version >= "3.9" and python_version < "4.0"
django-js-asset==2.1.0 ; python_version >= "3.9" and python_version < "4.0"
django-phonenumber-field[phonenumbers]==5.2.0 ; python_version >= "3.9" and python_version < "4.0"
django-polymorphic==3.1.0 ; python_version >= "3.9" and python_version < "4.0"
django-private-storage==3.1.1 ; python_version >= "3.9" and python_version < "4.0"
django-rest-multiple-models==2.1.3 ; python_version >= "3.9" and python_version < "4.0"
django==3.2.25 ; python_version >= "3.9" and python_version < "4.0"
djangorestframework==3.13.1 ; python_version >= "3.9" and python_version < "4.0"
Expand Down
1 change: 1 addition & 0 deletions requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ django-filter==21.1 ; python_version >= "3.9" and python_version < "4.0"
django-js-asset==2.1.0 ; python_version >= "3.9" and python_version < "4.0"
django-phonenumber-field[phonenumbers]==5.2.0 ; python_version >= "3.9" and python_version < "4.0"
django-polymorphic==3.1.0 ; python_version >= "3.9" and python_version < "4.0"
django-private-storage==3.1.1 ; python_version >= "3.9" and python_version < "4.0"
django-rest-multiple-models==2.1.3 ; python_version >= "3.9" and python_version < "4.0"
django==3.2.25 ; python_version >= "3.9" and python_version < "4.0"
djangorestframework==3.13.1 ; python_version >= "3.9" and python_version < "4.0"
Expand Down
Loading