def url(self, name): if hasattr(self.connection, 'make_blob_url'): if self.auto_sign: access_policy = AccessPolicy() access_policy.start = ( datetime.utcnow() + timedelta(seconds=-120)).strftime('%Y-%m-%dT%H:%M:%SZ') access_policy.expiry = (datetime.utcnow() + timedelta( seconds=self.ap_expiry)).strftime('%Y-%m-%dT%H:%M:%SZ') access_policy.permission = self.azure_access_policy_permission sap = SharedAccessPolicy(access_policy) sas_token = self.connection.generate_shared_access_signature( self.azure_container, blob_name=name, shared_access_policy=sap, ) else: sas_token = None return self.connection.make_blob_url( container_name=self.azure_container, blob_name=name, protocol=self.azure_protocol, sas_token=sas_token, ) else: return "{}{}/{}".format(setting('MEDIA_URL'), self.azure_container, name)
def make_blob_sas_url(account_name, account_key, container_name, blob_name, permission='w', duration=16): """ Generate a Blob SAS URL to allow a client to upload a file. account_name: Storage account name. account_key: Storage account key. container_name: Storage container. blob_name: Blob name. duration: A timedelta representing duration until SAS expiration. SAS start date will be utcnow() minus one minute. Expiry date is start date plus duration. Returns the SAS URL. """ sas = SharedAccessSignature(account_name, account_key) resource_path = '%s/%s' % (container_name, blob_name) date_format = "%Y-%m-%dT%H:%M:%SZ" start = datetime.datetime.utcnow() - datetime.timedelta(minutes=5) expiry = start + datetime.timedelta(minutes=duration) sap = SharedAccessPolicy(AccessPolicy( start.strftime(date_format), expiry.strftime(date_format), permission)) sas_token = sas.generate_signed_query_string(resource_path, 'b', sap) blob_url = BlobService(account_name, account_key) url = blob_url.make_blob_url(container_name=container_name, blob_name=blob_name, sas_token=sas_token) return url
def test_generate_signed_query_dict_blob_with_access_policy_and_headers( self): accss_plcy = AccessPolicy() accss_plcy.start = '2011-10-11T11:03:40Z' accss_plcy.expiry = '2011-10-12T11:53:40Z' accss_plcy.permission = 'r' query = self.sas._generate_signed_query_dict( 'images/pic1.png', ResourceType.RESOURCE_BLOB, SharedAccessPolicy(accss_plcy), content_disposition='file; attachment', content_type='binary', ) self.assertEqual(query[QueryStringConstants.SIGNED_START], '2011-10-11T11:03:40Z') self.assertEqual(query[QueryStringConstants.SIGNED_EXPIRY], '2011-10-12T11:53:40Z') self.assertEqual(query[QueryStringConstants.SIGNED_RESOURCE], ResourceType.RESOURCE_BLOB) self.assertEqual(query[QueryStringConstants.SIGNED_PERMISSION], 'r') self.assertEqual( query[QueryStringConstants.SIGNED_CONTENT_DISPOSITION], 'file; attachment') self.assertEqual(query[QueryStringConstants.SIGNED_CONTENT_TYPE], 'binary') self.assertEqual(query[QueryStringConstants.SIGNED_SIGNATURE], 'uHckUC6T+BwUsc+DgrreyIS1k6au7uUd7LSSs/z+/+w=')
def url(self, name): """ Override this method so that we can add SAS authorization tokens """ sas_token = None if self.url_expiry_secs: now = datetime.utcnow().replace(tzinfo=pytz.utc) expire_at = now + timedelta(seconds=self.url_expiry_secs) policy = AccessPolicy() # generate an ISO8601 time string and use split() to remove the sub-second # components as Azure will reject them. Plus add the timezone at the end. policy.expiry = expire_at.isoformat().split('.')[0] + 'Z' policy.permission = 'r' sas_token = self.connection.generate_shared_access_signature( self.azure_container, blob_name=name, shared_access_policy=SharedAccessPolicy(access_policy=policy), ) return self.connection.make_blob_url( container_name=self.azure_container, blob_name=name, protocol=self.azure_protocol, sas_token=sas_token)
def _get_shared_access_policy(self, permission): date_format = "%Y-%m-%dT%H:%M:%SZ" start = datetime.datetime.utcnow() - datetime.timedelta(minutes=1) expiry = start + datetime.timedelta(hours=1) return SharedAccessPolicy( AccessPolicy(start.strftime(date_format), expiry.strftime(date_format), permission))
def request_upload(upload_location): filetype = request.args.get("filetype") filesize = request.args.get("filesize") if filetype not in ['png', 'jpg', 'jpeg', 'gif', 'pdf']: return "Invalid filetype", 400 # TODO: Check filesize if upload_location not in ["event", "user", "project"]: return "Invalid upload location", 400 token = request.headers.get('session') user_id = sessions.get('session:' + token) if not user_id: return "Session invalid", 40 user = User.find_id(user_id) if not user: return "Session invalid", 401 if upload_location == "event" and user.type != "organizer": return "You don't have permission to upload", 401 upload_policy = SharedAccessPolicy( AccessPolicy( start=( datetime.datetime.utcnow() - datetime.timedelta(minutes=15)).strftime("%Y-%m-%dT%H:%M:%SZ"), expiry=( datetime.datetime.utcnow() + datetime.timedelta(minutes=15)).strftime("%Y-%m-%dT%H:%M:%SZ"), permission=BlobSharedAccessPermissions.WRITE, )) destination_url = upload_location + "/" + create_filename( ) + '.' + filetype # TODO: fix "Incorrect Padding" exception on this line upload_token = azure_storage.generate_shared_access_signature( container_name='user-files', blob_name=destination_url, shared_access_policy=upload_policy, ) print("Created Destination Url " + destination_url) print("Created upload token " + upload_token) return json.dumps({ "upload_url": files_url + destination_url + "?" + upload_token, "file_url": files_url + destination_url }), 200, jsonType
def test_generate_signed_query_dict_container_with_signed_identifier(self): signed_identifier = 'YWJjZGVmZw==' query = self.sas._generate_signed_query_dict( 'images', ResourceType.RESOURCE_CONTAINER, SharedAccessPolicy(signed_identifier=signed_identifier), ) self.assertEqual(query[QueryStringConstants.SIGNED_RESOURCE], ResourceType.RESOURCE_CONTAINER) self.assertEqual(query[QueryStringConstants.SIGNED_IDENTIFIER], signed_identifier) self.assertEqual(query[QueryStringConstants.SIGNED_SIGNATURE], 'BbzpLHe+JxNAsW/v6LttP5x9DdGMvXsZpm2chKblr3s=')
def getPublicUrl(self, jobStoreFileID): try: self.files.get_blob_properties(blob_name=jobStoreFileID) except AzureMissingResourceHttpError: raise NoSuchFileException(jobStoreFileID) # Compensate of a little bit of clock skew startTimeStr = (datetime.utcnow() - timedelta(minutes=5)).strftime(self._azureTimeFormat) endTime = datetime.utcnow() + self.publicUrlExpiration endTimeStr = endTime.strftime(self._azureTimeFormat) sap = SharedAccessPolicy(AccessPolicy(startTimeStr, endTimeStr, BlobSharedAccessPermissions.READ)) sas_token = self.files.generate_shared_access_signature(blob_name=jobStoreFileID, shared_access_policy=sap) return self.files.make_blob_url(blob_name=jobStoreFileID) + '?' + sas_token
def request_video_upload_url(request, video_guid = None): blob_name = format_blob_name(user = request.user, video_guid = video_guid) expiry = (datetime.utcnow() + settings.AZURE_CONFIG['relative_expiry_time']).strftime('%Y-%m-%dT%H:%M:%SZ') ap = AccessPolicy( expiry = expiry, permission = 'w') qs = shared_access_signature.generate_signed_query_string( path = settings.AZURE_CONFIG['video_upload_container'] + '/' + blob_name, resource_type= 'b', shared_access_policy = SharedAccessPolicy(access_policy = ap)) return blob_service.make_blob_url( container_name = settings.AZURE_CONFIG['video_upload_container'], blob_name = blob_name) + '?' + urllib.urlencode(qs)
def test_generate_signed_query_dict_blob_with_access_policy(self): accss_plcy = AccessPolicy() accss_plcy.start = '2011-10-11' accss_plcy.expiry = '2011-10-12' accss_plcy.permission = 'w' query = self.sas._generate_signed_query_dict( 'images/pic1.png', ResourceType.RESOURCE_BLOB, SharedAccessPolicy(accss_plcy), ) self.assertEqual(query[QueryStringConstants.SIGNED_START], '2011-10-11') self.assertEqual(query[QueryStringConstants.SIGNED_EXPIRY], '2011-10-12') self.assertEqual(query[QueryStringConstants.SIGNED_RESOURCE], ResourceType.RESOURCE_BLOB) self.assertEqual(query[QueryStringConstants.SIGNED_PERMISSION], 'w') self.assertEqual(query[QueryStringConstants.SIGNED_SIGNATURE], 'Fqt8tNcyUOp30qYRtSFNcImrRMcxlk6IF17O4l96KT8=')
def test_generate_signed_query_dict_container_with_access_policy(self): accss_plcy = AccessPolicy() accss_plcy.start = '2011-10-11' accss_plcy.expiry = '2011-10-12' accss_plcy.permission = 'r' query = self.sas._generate_signed_query_dict( 'images', ResourceType.RESOURCE_CONTAINER, SharedAccessPolicy(accss_plcy), ) self.assertEqual(query[QueryStringConstants.SIGNED_START], '2011-10-11') self.assertEqual(query[QueryStringConstants.SIGNED_EXPIRY], '2011-10-12') self.assertEqual(query[QueryStringConstants.SIGNED_RESOURCE], ResourceType.RESOURCE_CONTAINER) self.assertEqual(query[QueryStringConstants.SIGNED_PERMISSION], 'r') self.assertEqual(query[QueryStringConstants.SIGNED_SIGNATURE], 'CxLWN56cjXidpI9em7RDgSN2QIgLggTqrnzudH2XsOY=')
def url(self, name): """ Returns the URL where the contents of the file referenced by name can be accessed. """ try: m = hashlib.sha1() m.update(self.container) m.update(name) cache_key = m.hexdigest() val = cache.get(cache_key) if val is None: logger.info("trying to generate shared access url for %s" % name) accss_plcy = AccessPolicy() now = datetime.datetime.now() today = now.strftime('%Y-%m-%d') tomorrow_datetime = now + datetime.timedelta(days=1) tomorrow = tomorrow_datetime.strftime('%Y-%m-%d') accss_plcy.start = today accss_plcy.expiry = tomorrow accss_plcy.permission = 'r' signed_identifier = None sap = SharedAccessPolicy(accss_plcy, signed_identifier) logger.info("shared access policy created") signer = SharedAccessSignature(account_name=self.account_name, account_key=self.account_key) logger.info("signed created") qry_str = signer.generate_signed_query_string( "%s/%s" % (self.container, name), 'b', sap) logger.info("signed query string created") val = '%s/%s?%s' % (self._get_container_url(), name, signer._convert_query_string(qry_str)) # cache for 23 hours timeout = 60 * 60 * 23 cache.set(cache_key, val, timeout) return val else: logger.info("url cache hit for %s" % name) return val except Exception as ex: logger.error("shared access error %s" % ex) return None
def make_blob_sas_url(account_name, account_key, container_name, blob_name, permission='w', duration=16): """ Generate a Blob SAS URL to allow a client to upload a file. account_name: Storage account name. account_key: Storage account key. container_name: Storage container. blob_name: Blob name. duration: A timedelta representing duration until SAS expiration. SAS start date will be utcnow() minus one minute. Expiry date is start date plus duration. Returns the SAS URL. """ sas = SharedAccessSignature(account_name, account_key) resource_path = '%s/%s' % (container_name, blob_name) date_format = "%Y-%m-%dT%H:%M:%SZ" start = datetime.datetime.utcnow() - datetime.timedelta(minutes=5) expiry = start + datetime.timedelta(minutes=duration) sap = SharedAccessPolicy( AccessPolicy(start.strftime(date_format), expiry.strftime(date_format), permission)) signed_query = sas.generate_signed_query_string(resource_path, RESOURCE_BLOB, sap) sas.permission_set = [Permission('/' + resource_path, signed_query)] res = WebResource() res.properties[SIGNED_RESOURCE_TYPE] = RESOURCE_BLOB res.properties[SHARED_ACCESS_PERMISSION] = permission res.path = '/{0}'.format(resource_path) res.request_url = 'https://{0}.blob.core.windows.net/{1}/{2}'.format( account_name, container_name, blob_name) res = sas.sign_request(res) return res.request_url
def test_sas_signed_identifier(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recordingfile(self.test_mode): return # Arrange si = SignedIdentifier() si.id = 'testid' si.access_policy.start = '2011-10-11' si.access_policy.expiry = '2018-10-12' si.access_policy.permission = QueueSharedAccessPermissions.READ identifiers = SignedIdentifiers() identifiers.signed_identifiers.append(si) resp = self.qs.set_queue_acl(self.test_queues[0], identifiers) self.qs.put_message(self.test_queues[0], 'message1') token = self.qs.generate_shared_access_signature( self.test_queues[0], SharedAccessPolicy(signed_identifier=si.id), ) # Act service = QueueService( account_name=self.settings.STORAGE_ACCOUNT_NAME, sas_token=token, ) self._set_service_options(service, self.settings) result = service.peek_messages(self.test_queues[0]) # Assert self.assertIsNotNone(result) self.assertEqual(1, len(result)) message = result[0] self.assertIsNotNone(message) self.assertNotEqual('', message.message_id) self.assertEqual('message1', message.message_text)
print('Container Name:',storage_container_name) print('Input file:',inputfile) print('Output Blob:',outputblob) blob_service = BlobService(account_name=storage_account_name, account_key = storage_account_key) #blob_service.create_container(storage_container_name,x_ms_blob_public_access='containter') blob_service.put_block_blob_from_path(storage_container_name, outputblob,inputfile,x_ms_blob_content_type="image/jpeg") #this access policy is valid for four minutes (now -120 seconds until now + 120 seconds) to account for clock skew ap= AccessPolicy( start = (datetime.datetime.utcnow() + datetime.timedelta(seconds=-120)).strftime('%Y-%m-%dT%H:%M:%SZ'), expiry = (datetime.datetime.utcnow() + datetime.timedelta(seconds=120)).strftime('%Y-%m-%dT%H:%M:%SZ'), permission=BlobSharedAccessPermissions.READ, ) sas_token = blob_service.generate_shared_access_signature( container_name=storage_container_name, blob_name=outputblob, shared_access_policy=SharedAccessPolicy(ap), ) url = blob_service.make_blob_url( container_name=storage_container_name, blob_name=outputblob, sas_token=sas_token, ) print('URL is:',url) #even if the blob is not public, it can be accessed with this URL if __name__=='__main__': parser = argparse.ArgumentParser() parser.add_argument('-n', '--storagename') parser.add_argument('-k', '--storagekey') parser.add_argument('-c', '--containername')