защита загруженных пользователем файлов django - PullRequest
3 голосов
/ 26 февраля 2012

Как я могу разрешить пользователям загружать файлы в свою собственную, назначенную пользователем папку и видеть только те файлы, которые они загрузили?Я использую передачу файлов Django.В настоящее время он дает мне выбор, в какой файл помещать мультимедиа, но я могу поместить его в файл любого пользователя и просматривать мультимедиа каждого пользователя.Вот мои загрузки / models.py:

from django.db import models
from django.contrib.auth.models import User, UserManager

def uploadmodel_file_upload_to(instance, filename):
    print 'instance.user.username = '+ str(instance.user.username)
    return 'uploads/%s/%s' % (instance.user.username, filename)

class UploadModel(models.Model):
    user = models.ForeignKey('auth.user')
    file = models.FileField(upload_to=uploadmodel_file_upload_to)

1 Ответ

5 голосов
/ 26 февраля 2012

uploadmodel_file_upload_to возвращает относительный путь. Чтобы построить полный путь, django добавляет настройки. MEDIA_ROOT. MEDIA_ROOT должен быть общедоступным.

Итак, мы хотим сохранить файл вне MEDIA_ROOT. Добавьте что-то вроде этого в settings.py:

import os.path
PROJECT_ROOT=os.path.abspath(os.path.dirname(__file__))
PROTECTED_MEDIA_ROOT=os.path.join(PROJECT_ROOT, 'protected_uploads')

Теперь вы можете обновить uploadmodel_file_upload_to, чтобы он возвращал абсолютный путь:

def uploadmodel_file_upload_to(instance, filename):
    return '%s/%s/%s' % (settings.PROTECTED_MEDIA_ROOT, instance.user.username,
        filename)

Теперь, когда файлы сохранены в / project / path / protected_uploads, нам нужно добавить представление для его обслуживания, например:

import os 
import mimetypes

from django import shortcuts
from django import http
from django.conf import settings
from django.views.static import was_modified_since
from django.utils.http import http_date

from .models import *

def serve_upload(request, upload_id):
    upload = shortcuts.get_object_or_404(UploadModel, pk=upload_id)
    fullpath = upload.file.path

    if request.user != upload.user:
        return http.HttpResponseForbidden()

    statobj = os.stat(fullpath)
    mimetype, encoding = mimetypes.guess_type(fullpath)
    mimetype = mimetype or 'application/octet-stream'
    if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
                              statobj.st_mtime, statobj.st_size):
        return http.HttpResponseNotModified(mimetype=mimetype)
    response = http.HttpResponse(open(fullpath, 'rb').read(), mimetype=mimetype)
    response["Last-Modified"] = http_date(statobj.st_mtime)
    response["Content-Length"] = statobj.st_size
    if encoding:
        response["Content-Encoding"] = encoding
    return response

И URL:

url(r'serve_upload/(?P<upload_id>\d+)/$', 'serve_upload'),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...