addons-server/apps/files/decorators.py

98 строки
3.1 KiB
Python

from datetime import datetime
import functools
from django import http
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404
from django.utils.http import http_date
from amo.utils import Token
from access.acl import check_addon_ownership, action_allowed
from files.helpers import DiffHelper, FileViewer
from files.models import File
def allowed(request, file):
allowed = action_allowed(request, 'Editors', '%')
if not allowed:
try:
addon = file.version.addon
except ObjectDoesNotExist:
return http.Http404()
if addon.view_source:
allowed = True
else:
allowed = check_addon_ownership(request, addon,
viewer=True, dev=True)
if not allowed:
return http.HttpResponseForbidden()
return True
def _get_value(obj, key, value, cast=None):
obj = getattr(obj, 'left', obj)
key = obj.get_default(key)
obj.select(key)
if obj.selected:
value = obj.selected.get(value)
return cast(value) if cast else value
def last_modified(request, obj, key=None):
return _get_value(obj, key, 'modified', datetime.fromtimestamp)
def etag(request, obj, key=None):
return _get_value(obj, key, 'md5')
def file_view(func, **kwargs):
@functools.wraps(func)
def wrapper(request, file_id, *args, **kw):
file = get_object_or_404(File, pk=file_id)
result = allowed(request, file)
if result is not True:
return result
obj = FileViewer(file)
response = func(request, obj, *args, **kw)
if obj.selected:
response['ETag'] = '"%s"' % obj.selected.get('md5')
response['Last-Modified'] = http_date(obj.selected.get('modified'))
return response
return wrapper
def compare_file_view(func, **kwargs):
@functools.wraps(func)
def wrapper(request, one_id, two_id, *args, **kw):
one = get_object_or_404(File, pk=one_id)
two = get_object_or_404(File, pk=two_id)
for obj in [one, two]:
result = allowed(request, obj)
if result is not True:
return result
obj = DiffHelper(one, two)
response = func(request, obj, *args, **kw)
if obj.left.selected:
response['ETag'] = '"%s"' % obj.left.selected.get('md5')
response['Last-Modified'] = http_date(obj.left.selected
.get('modified'))
return response
return wrapper
def file_view_token(func, **kwargs):
@functools.wraps(func)
def wrapper(request, file_id, key, *args, **kw):
viewer = FileViewer(get_object_or_404(File, pk=file_id))
token = request.GET.get('token')
if not token:
return http.HttpResponseForbidden()
if not Token.valid(token, [request.META.get('REMOTE_ADDR'),
viewer.file.id, key]):
return http.HttpResponseForbidden()
return func(request, viewer, key, *args, **kw)
return wrapper