Skip to content

Commit

Permalink
Merge e107662 into a679f36
Browse files Browse the repository at this point in the history
  • Loading branch information
matllubos committed Oct 14, 2019
2 parents a679f36 + e107662 commit e0ae69e
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 40 deletions.
26 changes: 20 additions & 6 deletions chamber/config.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
from django.conf import settings
from django.conf import settings as django_settings


CHAMBER_MAX_FILE_UPLOAD_SIZE = getattr(settings, 'CHAMBER_MAX_FILE_UPLOAD_SIZE', 20)
CHAMBER_MULTIDOMAINS_OVERTAKER_AUTH_COOKIE_NAME = getattr(settings, 'CHAMBER_MULTIDOMAINS_OVERTAKER_AUTH_COOKIE_NAME',
None)
CHAMBER_DEFAULT_IMAGE_ALLOWED_CONTENT_TYPES = getattr(settings, 'CHAMBER_DEFAULT_IMAGE_ALLOWED_CONTENT_TYPES',
{'image/jpeg', 'image/png', 'image/gif'})
DEFAULTS = {
'MAX_FILE_UPLOAD_SIZE': 20,
'MULTIDOMAINS_OVERTAKER_AUTH_COOKIE_NAME': None,
'DEFAULT_IMAGE_ALLOWED_CONTENT_TYPES': {'image/jpeg', 'image/png', 'image/gif'},
'PRIVATE_S3_STORAGE_URL_EXPIRATION': 3600,
}


class Settings:

def __getattr__(self, attr):
if attr not in DEFAULTS:
raise AttributeError('Invalid CHAMBER setting: "{}"'.format(attr))

default = DEFAULTS[attr]
return getattr(django_settings, 'CHAMBER_{}'.format(attr), default(self) if callable(default) else default)


settings = Settings()
4 changes: 2 additions & 2 deletions chamber/forms/fields.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django import forms
from django.utils.translation import ugettext

from chamber import config
from chamber.config import settings

from .validators import (
RestrictedFileValidator, AllowedContentTypesByFilenameFileValidator, AllowedContentTypesByContentFileValidator
Expand Down Expand Up @@ -48,7 +48,7 @@ def __init__(self, *args, **kwargs):
class RestrictedFileField(forms.FileField):

def __init__(self, *args, **kwargs):
max_upload_size = kwargs.pop('max_upload_size', config.CHAMBER_MAX_FILE_UPLOAD_SIZE) * 1024 * 1024
max_upload_size = kwargs.pop('max_upload_size', settings.MAX_FILE_UPLOAD_SIZE) * 1024 * 1024
allowed_content_types = kwargs.pop('allowed_content_types', None)

validators = tuple(kwargs.pop('validators', [])) + (
Expand Down
7 changes: 3 additions & 4 deletions chamber/models/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
from django.db import models
from django.db.models import FileField as OriginFileField
from django.db.models.fields import DecimalField as OriginDecimalField
from django.forms import forms
from django.utils.encoding import force_text
from django.utils.translation import ugettext

from chamber import config
from chamber.config import settings
from chamber.forms import fields as chamber_fields
from chamber.forms.validators import (
RestrictedFileValidator, AllowedContentTypesByFilenameFileValidator, AllowedContentTypesByContentFileValidator
Expand Down Expand Up @@ -56,7 +55,7 @@ class RestrictedFileFieldMixin:
* max_upload_size - a number indicating the maximum file size allowed for upload in MB.
"""
def __init__(self, *args, **kwargs):
max_upload_size = kwargs.pop('max_upload_size', config.CHAMBER_MAX_FILE_UPLOAD_SIZE) * 1024 * 1024
max_upload_size = kwargs.pop('max_upload_size', settings.MAX_FILE_UPLOAD_SIZE) * 1024 * 1024
allowed_content_types = kwargs.pop('allowed_content_types', None)
super().__init__(*args, **kwargs)
self.validators.append(RestrictedFileValidator(max_upload_size))
Expand All @@ -82,7 +81,7 @@ class FileField(RestrictedFileFieldMixin, OriginFileField):
class ImageField(RestrictedFileFieldMixin, OriginImageField):

def __init__(self, *args, **kwargs):
allowed_content_types = kwargs.pop('allowed_content_types', config.CHAMBER_DEFAULT_IMAGE_ALLOWED_CONTENT_TYPES)
allowed_content_types = kwargs.pop('allowed_content_types', settings.DEFAULT_IMAGE_ALLOWED_CONTENT_TYPES)
super().__init__(allowed_content_types=allowed_content_types, *args, **kwargs)


Expand Down
4 changes: 2 additions & 2 deletions chamber/multidomains/auth/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from auth_token.models import Token # pylint: disable=E0401
from auth_token.utils import dont_enforce_csrf_checks, header_name_to_django # pylint: disable=E0401

from chamber import config
from chamber.config import settings
from chamber.shortcuts import get_object_or_none


Expand All @@ -17,7 +17,7 @@ def get_token(request):
"""
if (not request.META.get(header_name_to_django(auth_token_settings.HEADER_NAME)) and
config.CHAMBER_MULTIDOMAINS_OVERTAKER_AUTH_COOKIE_NAME):
ovetaker_auth_token = request.COOKIES.get(config.CHAMBER_MULTIDOMAINS_OVERTAKER_AUTH_COOKIE_NAME)
ovetaker_auth_token = request.COOKIES.get(settings.MULTIDOMAINS_OVERTAKER_AUTH_COOKIE_NAME)
token = get_object_or_none(Token, key=ovetaker_auth_token, is_active=True)
if utils.get_user_from_token(token).is_authenticated():
return token
Expand Down
62 changes: 36 additions & 26 deletions chamber/storages/boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@

from storages.backends.s3boto3 import S3Boto3Storage

from chamber.config import settings


__all__ = (
'S3Storage',
'BaseS3Storage',
'BasePrivateS3Storage',
'BasePrivateS3DataStorage',
'force_bytes_content',
'get_storage_instance',
's3_presigned_download_url',
)


Expand All @@ -30,36 +33,43 @@ def force_bytes_content(content, blocksize=1024):
return content, False


def s3_presigned_download_url(url=None, file=None, expiration=3600):
if not url and not file:
raise ValueError('You must provide either a "url" or "file".')

if url:
return url
if not settings.AWS_S3_ON:
return file.url

s3 = boto3.client('s3', config=Config(region_name=settings.AWS_REGION, signature_version='s3v4'))
url = s3.generate_presigned_url(
'get_object',
Params={
'Bucket': file.storage.bucket_name,
'Key': file.storage.get_full_relative_path(file.name),
},
ExpiresIn=expiration,
)
return url
def get_storage_class(s3_storage_class, default_storage_class=DefaultStorage):
return storage_class if settings.AWS_S3_ON else default_storage_class


def get_storage_instance(storage_class, default_storage_class=DefaultStorage):
return storage_class() if settings.AWS_S3_ON else default_storage_class()
def get_storage_instance(s3_storage_class, default_storage_class=DefaultStorage):
return s3_storage_class() if settings.AWS_S3_ON else default_storage_class()


class S3Storage(S3Boto3Storage):
class BaseS3Storage(S3Boto3Storage):

def get_full_relative_path(self, filename):
return '{}/{}'.format(self.location, filename) if self.location else filename
def _clean_name(self, name):
# pathlib support
return super()._clean_name(str(name))

def save(self, name, content, max_length=None):
content, _ = force_bytes_content(content)
return super().save(name, content, max_length)


class BasePrivateS3Storage(BaseS3Storage):

expiration = settings.PRIVATE_S3_STORAGE_URL_EXPIRATION

def url(self, name):
s3 = boto3.client('s3', config=Config(region_name=settings.AWS_REGION, signature_version='s3v4'))
url = s3.generate_presigned_url(
'get_object',
Params={
'Bucket': self.bucket_name,
'Key': self._normalize_name(name),
},
ExpiresIn=self.expiration,
)
return url


class BasePrivateS3DataStorage(S3Boto3Storage):

def url(self, name):
raise RuntimeError('You cannot generate data storage URL')

0 comments on commit e0ae69e

Please sign in to comment.