Serving media based on authorization checks
The app is tested on Django 3.2.25 with Python 3.6.8, and has no dependency from other packages
pip install git+https://github.com/depaolim/django_auth_media.git
Steps:
-
Use auth_media.AuthMediaField in place of models.FileField
from django.db import models from auth_media import AuthFileField class MediaModel(models.Model): media_field = AuthFileField( upload_to="media_model_folder", permission="testapp.view_mediamodel")
AuthFileField expects the following params:
- permission: string or callable
- string specify a permission full-name, or
- callable with the following parameters (model_instance, request)
- media_server: server name as defined in settings.MEDIA_SERVERS (see below)
- permission: string or callable
-
Add urlpatterns in urls.py
import auth_media urlpatterns += auth_media.urlpatterns()
-
Add MEDIA_URL and MEDIA_ROOT in settings.py
MEDIA_URL = '/media/' MEDIA_ROOT = 'path_to_files_on_file_system'
-
Add MEDIA_SERVERS in settings.py
Example:
MEDIA_SERVERS = { 'default': { 'ENGINE': "auth_media.backends.interim", }, 'xaccel': { 'ENGINE': "auth_media.backends.xaccel", 'REDIRECT': "/internal_media", }, 'secure': { 'ENGINE': "auth_media.backends.secure_link", 'SECRET': "SUpeRSecREt", 'REDIRECT': "/secure_media", }, }
- "interim" slow, should be used only in debug (wrapper for on django.views.static.serve)
- "xaccel" based on X-Accel-Redirect header as managed by nginx (similar to Apache X-Sendfile)
- "secure_link" based on secure_link mechanism managed by nginx
Engine function must define two positional arguments:
- request: the current request object
- path: as returned by property field.name
Other key-value (ex. REDIRECT or SECRET) specified inside each media_server definition, are used as "named parameters" automatically binded to engine function
It is easy to define new media servers and plug them in auth_media
If you you define new general-purpose media-servers please let me know and I will be happy to integrate them in auth_media core
Use the same path used in "internal location" in nginx config. Example:
settings.py:
'xaccel': {
'ENGINE': "auth_media.backends.xaccel",
'REDIRECT': "/internal_media",
},
nginx.conf:
location /internal_media {
internal;
alias /path_to_media_files;
}
Reference: http://wiki.nginx.org/X-accel
Use the same path used in "rewrite location" in nginx config. Example:
'secure': {
'ENGINE': "auth_media.backends.secure_link",
'SECRET': "SUpeRSecREt",
'REDIRECT': "/secure_media",
},
nginx.conf:
location /secure_media/ {
secure_link_secret SUpeRSecREt;
if ($secure_link = "") {
return 403;
}
rewrite ^ /path_to_media_files/$secure_link;
}
Reference: http://nginx.org/en/docs/http/ngx\_http\_secure\_link\_module.html
To run tests (you need pyenv):
make test
To build a package:
make deploy
distributable package is saved in "dist" folder
To cleanup:
make clean
Riccardo Magliocchetti https://github.com/xrmx
- code-reviews and many hints
Manlio Perillo https://github.com/perillo
- made me discover nginx secure_links