def url(self, name): if name.startswith('http://') or name.startswith('https://'): return name if self.secure_urls: # Get crypted url from cloudfront, ex : https://media.cbien.com name = self._normalize_name(self._clean_name(name)) url = "%s//%s" % (self.url_protocol, os.path.join(self.custom_domain, self.custom_path, name)) dist = Distribution() return dist.create_signed_url( url=url, keypair_id=settings.CLOUDFRONT_KEY_PAIR_ID, private_key_string=settings.CLOUDFRONT_PRIVATE_KEY, expire_time=int(time.time() + int(settings.CLOUDFRONT_ROTATION_SECONDS))) elif self.signed_urls: name = os.path.join(self.location, name) return self.connection.generate_url( self.querystring_expire, method='GET', bucket=self.bucket.name, key=self._encode_name(name), query_auth=self.querystring_auth, force_http=not self.secure_urls) else: name = self._normalize_name(self._clean_name(name)) return "%s//%s" % (self.url_protocol, os.path.join(self.custom_domain, name))
def __init__(self, settings): super(Repository, self).__init__(settings) self.type = "cloudfront" self.checkSettings() # Needed for creating signed url self.distribution = Distribution() self.checkVcdbFile()
def create_url_params(expires=None): dist = Distribution() if expires is None: expires = int(time.time() + AWS_URL_SIGNING_EXPIRATION_DEFAULT) return dist.create_signed_url( '', current_app.config['AWS_ACCESS_KEY_ID'], expire_time=expires, private_key_string=current_app.config['AWS_URL_SIGNING_KEY'], policy_url='http*://cdn.croplands.org/*')
def get_distribution_info(self, distribution_id): response = self.make_request( 'GET', '/%s/distribution/%s' % (self.Version, distribution_id)) body = response.read() if response.status >= 300: raise CloudFrontServerError(response.status, response.reason, body) d = Distribution(connection=self) response_headers = response.msg for key in response_headers.keys(): if key.lower() == 'etag': d.etag = response_headers[key] h = handler.XmlHandler(d, self) xml.sax.parseString(body, h) return d
def setUp(self): self.pk_str = dedent(""" -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDA7ki9gI/lRygIoOjV1yymgx6FYFlzJ+z1ATMaLo57nL57AavW hb68HYY8EA0GJU9xQdMVaHBogF3eiCWYXSUZCWM/+M5+ZcdQraRRScucmn6g4EvY 2K4W2pxbqH8vmUikPxir41EeBPLjMOzKvbzzQy9e/zzIQVREKSp/7y1mywIDAQAB AoGABc7mp7XYHynuPZxChjWNJZIq+A73gm0ASDv6At7F8Vi9r0xUlQe/v0AQS3yc N8QlyR4XMbzMLYk3yjxFDXo4ZKQtOGzLGteCU2srANiLv26/imXA8FVidZftTAtL viWQZBVPTeYIA69ATUYPEq0a5u5wjGyUOij9OWyuy01mbPkCQQDluYoNpPOekQ0Z WrPgJ5rxc8f6zG37ZVoDBiexqtVShIF5W3xYuWhW5kYb0hliYfkq15cS7t9m95h3 1QJf/xI/AkEA1v9l/WN1a1N3rOK4VGoCokx7kR2SyTMSbZgF9IWJNOugR/WZw7HT njipO3c9dy1Ms9pUKwUF46d7049ck8HwdQJARgrSKuLWXMyBH+/l1Dx/I4tXuAJI rlPyo+VmiOc7b5NzHptkSHEPfR9s1OK0VqjknclqCJ3Ig86OMEtEFBzjZQJBAKYz 470hcPkaGk7tKYAgP48FvxRsnzeooptURW5E+M+PQ2W9iDPPOX9739+Xi02hGEWF B0IGbQoTRFdE4VVcPK0CQQCeS84lODlC0Y2BZv2JxW3Osv/WkUQ4dslfAQl1T303 7uwwr7XTroMv8dIFQIPreoPhRKmd/SbJzbiKfS/4QDhU -----END RSA PRIVATE KEY----- """) self.pk_id = "PK123456789754" self.dist = Distribution() self.canned_policy = ( '{"Statement":[{"Resource":' '"http://d604721fxaaqy9.cloudfront.net/horizon.jpg' '?large=yes&license=yes",' '"Condition":{"DateLessThan":{"AWS:EpochTime":1258237200}}}]}') self.custom_policy_1 = ( '{ \n' ' "Statement": [{ \n' ' "Resource":"http://d604721fxaaqy9.cloudfront.net/training/*", \n' ' "Condition":{ \n' ' "IpAddress":{"AWS:SourceIp":"145.168.143.0/24"}, \n' ' "DateLessThan":{"AWS:EpochTime":1258237200} \n' ' } \n' ' }] \n' '}\n') self.custom_policy_2 = ( '{ \n' ' "Statement": [{ \n' ' "Resource":"http://*", \n' ' "Condition":{ \n' ' "IpAddress":{"AWS:SourceIp":"216.98.35.1/32"},\n' ' "DateGreaterThan":{"AWS:EpochTime":1241073790},\n' ' "DateLessThan":{"AWS:EpochTime":1255674716}\n' ' } \n' ' }] \n' '}\n')
def cloudfront_sign(asset_path, expiry=1485864000): cache_key = (u"%s_%s" % (asset_path, expiry)).encode("utf-8") cached_url = cloudfront_url_cache.get(cache_key, None) if cached_url: return cached_url cached_url = persistent_cloudfront_url_cache.get(cache_key, None) if cached_url: cloudfront_url_cache[cache_key] = cached_url return cached_url dist = Distribution(domain_name='d1gy1csjh89rhq.cloudfront.net') key_pair_id = 'APKAIQD6FQE7UOMX3R2Q' http_resource = 'https://assets.monsters-et-manus.com/' + asset_path http_signed_url = dist.create_signed_url(http_resource, key_pair_id, expiry, private_key_string=blueprint.cloudfront_private_key) cloudfront_url_cache[cache_key] = http_signed_url persistent_cloudfront_url_cache[cache_key] = http_signed_url return http_signed_url
def get_playlist_with_signed_url(playlist_path): # Get playlist file from S3 s3_conn = connect_s3(settings.ACCESS_KEY_ID, settings.SECRET_ACCESS_KEY) bucket = s3_conn.get_bucket(settings.PLAYLIST_BUCKET_NAME) key = bucket.get_key(playlist_path) if key is None: raise Exception("No such key was found. key={}".format(key)) fp = StringIO() key.get_contents_to_file(fp) fp.seek(0) # Convert with signed url cf_conn = CloudFrontConnection(settings.ACCESS_KEY_ID, settings.SECRET_ACCESS_KEY) dist = Distribution(cf_conn) expire_time = int(time.time() + 60 * 60) # 60 mins outlines = [] for line in fp.readlines(): line = line.rstrip() matchObj = re.search(TS_PATTERN, line) if matchObj is not None: file_name = matchObj.group() url = os.path.join( os.path.dirname( os.path.join(settings.CLOUDFRONT_URL_PREFIX, playlist_path)), file_name) signed_url = dist.create_signed_url( url, settings.CLOUDFRONT_KEYPAIR_ID, expire_time, private_key_file=settings.CLOUDFRONT_PRIVATE_KEY_FILE_LOCATION) outlines.append(signed_url) else: outlines.append(line) fp.close() return '\n'.join(outlines)
def create_distribution(self, origin, enabled, caller_reference='', cnames=None, comment=''): config = DistributionConfig(origin=origin, enabled=enabled, caller_reference=caller_reference, cnames=cnames, comment=comment) response = self.make_request('POST', '/%s/distribution' % self.Version, {'Content-Type': 'text/xml'}, data=config.to_xml()) body = response.read() if response.status == 201: d = Distribution(connection=self) h = handler.XmlHandler(d, self) xml.sax.parseString(body, h) return d else: raise CloudFrontServerError(response.status, response.reason, body)