class S3Storage(Storage):
    """Amazon Simple Storage Service"""

    def __init__(self, bucket=None, access_key=None, secret_key=None,
                 headers=None, calling_format=None, cache=None, base_url=None):
        if bucket is None:
            bucket = settings.AWS_STORAGE_BUCKET_NAME
        if calling_format is None:
           calling_format = getattr(settings, 'AWS_CALLING_FORMAT',
                                    CallingFormat.SUBDOMAIN)
        self.bucket = bucket

        if not access_key and not secret_key:
            access_key, secret_key = self._get_access_keys()

        self.connection = AWSAuthConnection(access_key, secret_key,
                            calling_format=calling_format)
        self.generator = QueryStringAuthGenerator(access_key, secret_key,
                            calling_format=calling_format,
                            is_secure=getattr(settings, 'AWS_S3_SECURE_URLS', False))
        self.generator.set_expires_in(getattr(settings, 'AWS_QUERYSTRING_EXPIRE', 60))

        default_headers = getattr(settings, HEADERS, [])
        # Backwards compatibility for original format from django-storages
        if isinstance(default_headers, dict):
            default_headers = [('.*', default_headers)]
        if headers:
            default_headers.update(headers)
        self.headers = []
        for value in default_headers:
            self.headers.append((re.compile(value[0]), value[1]))

        if cache is not None:
            self.cache = cache
        else:
            cache = getattr(settings, 'CUDDLYBUDDLY_STORAGE_S3_CACHE', None)
            if cache is not None:
                self.cache = self._get_cache_class(cache)()
            else:
                self.cache = None

        if base_url is None:
            base_url = settings.MEDIA_URL
        self.base_url = base_url

    def _get_cache_class(self, import_path=None):
        try:
            dot = import_path.rindex('.')
        except ValueError:
            raise ImproperlyConfigured("%s isn't a cache module." % import_path)
        module, classname = import_path[:dot], import_path[dot+1:]
        try:
            mod = import_module(module)
        except ImportError, e:
            raise ImproperlyConfigured('Error importing cache module %s: "%s"' % (module, e))
        try:
            return getattr(mod, classname)
        except AttributeError:
            raise ImproperlyConfigured('Cache module "%s" does not define a "%s" class.' % (module, classname))
def create_signed_url(file, expires=60, secure=False, private_cloudfront=False, expires_at=None):
    if not private_cloudfront:
        generator = QueryStringAuthGenerator(
            settings.AWS_ACCESS_KEY_ID,
            settings.AWS_SECRET_ACCESS_KEY,
            calling_format=getattr(settings, 'AWS_CALLING_FORMAT',
                                CallingFormat.SUBDOMAIN),
            is_secure=secure)
        generator.set_expires_in(expires)
        return generator.generate_url(
            'GET',
            settings.AWS_STORAGE_BUCKET_NAME,
            file
        )

    if secure and hasattr(settings.MEDIA_URL, 'https'):
        domain = settings.MEDIA_URL.https()
    else:
        if hasattr(settings.MEDIA_URL, 'match'):
            domain = settings.MEDIA_URL.match(file)
        else:
            domain = settings.MEDIA_URL
        if secure:
            domain = domain.replace('http://', 'https://')
        else:
            domain = domain.replace('https://', 'http://')

    url = urljoin(domain, iri_to_uri(file))

    if expires_at is None:
        expires = int(time.time() + expires)
    else:
        expires = expires_at

    policy = {
        'Statement': [{
            'Resource': url,
            'Condition': {
                'DateLessThan': {
                    'AWS:EpochTime': expires
                }
            }
        }]
    }

    key = settings.CUDDLYBUDDLY_STORAGE_S3_KEY_PAIR
    policy = json.dumps(policy, separators=(',',':'))
    sig = rsa.PrivateKey.load_pkcs1(key[1])
    sig = rsa.sign(policy, sig, 'SHA-1')
    sig = base64.b64encode(sig).replace('+', '-').replace('=', '_').replace('/', '~')

    return '%s%sExpires=%s&Signature=%s&Key-Pair-Id=%s' % (
        url,
        '&' if '?' in url else '?',
        expires,
        sig,
        key[0]
    )
def create_signed_url(file, expires=60, secure=False):
    generator = QueryStringAuthGenerator(settings.AWS_ACCESS_KEY_ID,
                                         settings.AWS_SECRET_ACCESS_KEY,
                                         calling_format=getattr(
                                             settings, 'AWS_CALLING_FORMAT',
                                             CallingFormat.SUBDOMAIN),
                                         is_secure=secure)
    generator.set_expires_in(expires)
    return generator.generate_url('GET', settings.AWS_STORAGE_BUCKET_NAME,
                                  file)
Example #4
0
def create_signed_url(file, expires=60, secure=False, private_cloudfront=False, expires_at=None):
    if not private_cloudfront:
        generator = QueryStringAuthGenerator(
            settings.AWS_ACCESS_KEY_ID,
            settings.AWS_SECRET_ACCESS_KEY,
            calling_format=getattr(settings, 'AWS_CALLING_FORMAT',
                                CallingFormat.SUBDOMAIN),
            is_secure=secure)
        generator.set_expires_in(expires)
        return generator.generate_url(
            'GET',
            settings.AWS_STORAGE_BUCKET_NAME,
            file
        )

    url = settings.MEDIA_URL
    if not isinstance(settings.MEDIA_URL, CloudFrontURLs):
        url = CloudFrontURLs(settings.MEDIA_URL)
    url = url.get_url(file, force_https=True if secure else False)

    if expires_at is None:
        expires = int(time.time() + expires)
    else:
        expires = expires_at

    # Use OrderedDict to keep things predictable and testable
    policy = OrderedDict()
    policy['Resource'] = url
    policy['Condition'] = {
        'DateLessThan': {
            'AWS:EpochTime': expires
        }
    }
    policy = {
        'Statement': [
            policy
        ]
    }
    policy = json.dumps(policy, separators=(',',':'))

    key = settings.CUDDLYBUDDLY_STORAGE_S3_KEY_PAIR
    dig = SHA.new()
    dig.update(policy.encode('utf-8'))
    sig = PKCS1_v1_5.new(RSA.importKey(key[1]))
    sig = sig.sign(dig)
    sig = base64.b64encode(sig).decode('utf-8')
    sig = sig.replace('+', '-').replace('=', '_').replace('/', '~')

    return '%s%sExpires=%s&Signature=%s&Key-Pair-Id=%s' % (
        url,
        '&' if '?' in url else '?',
        expires,
        sig,
        key[0]
    )
def create_signed_url(file, expires=60, secure=False):
    generator = QueryStringAuthGenerator(
        settings.AWS_ACCESS_KEY_ID,
        settings.AWS_SECRET_ACCESS_KEY,
        calling_format=getattr(settings, 'AWS_CALLING_FORMAT',
                               CallingFormat.SUBDOMAIN),
        is_secure=secure)
    generator.set_expires_in(expires)
    return generator.generate_url(
        'GET',
        settings.AWS_STORAGE_BUCKET_NAME,
        file
    )
Example #6
0
def create_signed_url(file,
                      expires=60,
                      secure=False,
                      private_cloudfront=False,
                      expires_at=None):
    if not private_cloudfront:
        generator = QueryStringAuthGenerator(
            settings.AWS_ACCESS_KEY_ID,
            settings.AWS_SECRET_ACCESS_KEY,
            calling_format=getattr(settings, 'AWS_CALLING_FORMAT',
                                   CallingFormat.SUBDOMAIN),
            is_secure=secure)
        generator.set_expires_in(expires)
        return generator.generate_url('GET', settings.AWS_STORAGE_BUCKET_NAME,
                                      file)

    url = settings.MEDIA_URL
    if not isinstance(settings.MEDIA_URL, CloudFrontURLs):
        url = CloudFrontURLs(settings.MEDIA_URL)
    url = url.get_url(file, force_https=True if secure else False)

    if expires_at is None:
        expires = int(time.time() + expires)
    else:
        expires = expires_at

    policy = {
        'Statement': [{
            'Resource': url,
            'Condition': {
                'DateLessThan': {
                    'AWS:EpochTime': expires
                }
            }
        }]
    }

    key = settings.CUDDLYBUDDLY_STORAGE_S3_KEY_PAIR
    policy = json.dumps(policy, separators=(',', ':'))
    sig = rsa.PrivateKey.load_pkcs1(key[1])
    sig = rsa.sign(policy, sig, 'SHA-1')
    sig = base64.b64encode(sig).replace('+',
                                        '-').replace('=',
                                                     '_').replace('/', '~')

    return '%s%sExpires=%s&Signature=%s&Key-Pair-Id=%s' % (
        url, '&' if '?' in url else '?', expires, sig, key[0])
    def __init__(self, bucket=None, access_key=None, secret_key=None,
                 headers=None, calling_format=None, cache=None, base_url=None):
        if bucket is None:
            bucket = settings.AWS_STORAGE_BUCKET_NAME
        if calling_format is None:
           calling_format = getattr(settings, 'AWS_CALLING_FORMAT',
                                    CallingFormat.SUBDOMAIN)
        self.bucket = bucket

        if not access_key and not secret_key:
            access_key, secret_key = self._get_access_keys()

        self.connection = AWSAuthConnection(access_key, secret_key,
                            calling_format=calling_format)
        self.generator = QueryStringAuthGenerator(access_key, secret_key,
                            calling_format=calling_format,
                            is_secure=getattr(settings, 'AWS_S3_SECURE_URLS', False))
        self.generator.set_expires_in(getattr(settings, 'AWS_QUERYSTRING_EXPIRE', 60))

        default_headers = getattr(settings, HEADERS, [])
        # Backwards compatibility for original format from django-storages
        if isinstance(default_headers, dict):
            default_headers = [('.*', default_headers)]
        if headers:
            default_headers.update(headers)
        self.headers = []
        for value in default_headers:
            self.headers.append((re.compile(value[0]), value[1]))

        if cache is not None:
            self.cache = cache
        else:
            cache = getattr(settings, 'CUDDLYBUDDLY_STORAGE_S3_CACHE', None)
            if cache is not None:
                self.cache = self._get_cache_class(cache)()
            else:
                self.cache = None

        if base_url is None:
            base_url = settings.MEDIA_URL
        self.base_url = base_url