Added HMAC authentication to image generation views

This commit is contained in:
Karl Hobley 2014-07-16 14:25:34 +01:00
parent 9545550281
commit a0af99488c
3 changed files with 23 additions and 3 deletions

View file

@ -3,5 +3,5 @@ from wagtail.wagtailimages.views import frontend
urlpatterns = [
url(r'^(\d*)/(.*)/$', frontend.serve, name='wagtailimages_serve'),
url(r'^(.*)/(\d*)/(.*)/$', frontend.serve, name='wagtailimages_serve'),
]

View file

@ -1,10 +1,15 @@
import os
import re
import base64
import hmac
import hashlib
from PIL import Image
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
def validate_image_format(f):
@ -68,3 +73,14 @@ def parse_filter_spec(filter_spec):
return OPERATION_NAMES[match.group(1)], (width, height)
raise InvalidFilterSpecError(filter_spec)
def generate_signature(image_id, filter_spec):
# Based on libthumbor hmac generation
# https://github.com/thumbor/libthumbor/blob/b19dc58cf84787e08c8e397ab322e86268bb4345/libthumbor/crypto.py#L50
url = str(image_id) + '/' + filter_spec + '/'
return base64.urlsafe_b64encode(hmac.new(settings.SECRET_KEY, url, hashlib.sha1).digest())
def verify_signature(signature, image_id, filter_spec):
return signature == generate_signature(image_id, filter_spec)

View file

@ -1,14 +1,18 @@
from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from django.core.exceptions import PermissionDenied
from wagtail.wagtailimages.models import get_image_model
from wagtail.wagtailimages.utils import InvalidFilterSpecError
from wagtail.wagtailimages.utils import InvalidFilterSpecError, verify_signature
from wagtail.wagtailimages import image_processor
def serve(request, image_id, filter_spec):
def serve(request, signature, image_id, filter_spec):
image = get_object_or_404(get_image_model(), id=image_id)
if not verify_signature(signature, image_id, filter_spec):
raise PermissionDenied
try:
return image_processor.process_image(image.file.file, HttpResponse(content_type='image/jpeg'), filter_spec)
except InvalidFilterSpecError: