def get_object(self, key): """Return the binary data contained in the key 'key' in the passed bucket Args: key (str): Key to access data in bucket Returns: bytes: Data referred to by key """ if self._par is None: from Acquire.Client import PARError raise PARError("You cannot read data from an empty OSPar") while key.startswith("/"): key = key[1:] url = self._url if url.endswith("/"): url = "%s%s" % (url, key) else: url = "%s/%s" % (url, key) if url.startswith("file://"): return _read_local(url) else: return _read_remote(url)
def get_object(self): """Return the binary data contained in this object""" if self._par is None: from Acquire.Client import PARError raise PARError("You cannot read data from an empty OSPar") url = self._url if url.startswith("file://"): return _read_local(url) else: return _read_remote(url)
def set_object(self, data): """Set the value of the object behind this OSPar to the binary 'data' """ if self._par is None: from Acquire.Client import PARError raise PARError("You cannot write data to an empty OSPar") url = self._url if url.startswith("file://"): return _write_local(url, data) else: return _write_remote(url, data)
def set_object(self, key, data): """Set the value of 'key' in 'bucket' to binary 'data'""" if self._par is None: from Acquire.Client import PARError raise PARError("You cannot write data to an empty OSPar") while key.startswith("/"): key = key[1:] url = self._url if url.endswith("/"): url = "%s%s" % (url, key) else: url = "%s/%s" % (url, key) if url.startswith("file://"): return _write_local(url, data) else: return _write_remote(url, data)
def create_par(bucket, encrypt_key, key=None, readable=True, writeable=False, duration=3600, cleanup_function=None): """Create a pre-authenticated request for the passed bucket and key (if key is None then the request is for the entire bucket). This will return a OSPar object that will contain a URL that can be used to access the object/bucket. If writeable is true, then the URL will also allow the object/bucket to be written to. PARs are time-limited. Set the lifetime in seconds by passing in 'duration' (by default this is one hour) Args: bucket (dict): Bucket to create OSPar for encrypt_key (PublicKey): Public key to encrypt PAR key (str, default=None): Key readable (bool, default=True): If bucket is readable writeable (bool, default=False): If bucket is writeable duration (int, default=3600): Duration OSPar should be valid for in seconds cleanup_function (function, default=None): Cleanup function to be passed to PARRegistry Returns: OSPar: Pre-authenticated request for the bucket """ from Acquire.Crypto import PublicKey as _PublicKey if not isinstance(encrypt_key, _PublicKey): from Acquire.Client import PARError raise PARError( "You must supply a valid PublicKey to encrypt the " "returned OSPar") # get the UTC datetime when this OSPar should expire from Acquire.ObjectStore import get_datetime_now as _get_datetime_now expires_datetime = _get_datetime_now() + \ _datetime.timedelta(seconds=duration) is_bucket = (key is None) # Limitation of OCI - cannot have a bucket OSPar with # read permissions! if is_bucket and readable: from Acquire.Client import PARError raise PARError( "You cannot create a Bucket OSPar that has read permissions " "due to a limitation in the underlying platform") try: from oci.object_storage.models import \ CreatePreauthenticatedRequestDetails as \ _CreatePreauthenticatedRequestDetails except: raise ImportError( "Cannot import OCI. Please install OCI, e.g. via " "'pip install oci' so that you can connect to the " "Oracle Cloud Infrastructure") oci_par = None request = _CreatePreauthenticatedRequestDetails() if is_bucket: request.access_type = "AnyObjectWrite" elif readable and writeable: request.access_type = "ObjectReadWrite" elif readable: request.access_type = "ObjectRead" elif writeable: request.access_type = "ObjectWrite" else: from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError( "Unsupported permissions model for OSPar!") request.name = str(_uuid.uuid4()) if not is_bucket: request.object_name = _clean_key(key) request.time_expires = expires_datetime client = bucket["client"] try: response = client.create_preauthenticated_request( client.get_namespace().data, bucket["bucket_name"], request) except Exception as e: # couldn't create the preauthenticated request from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError( "Unable to create the OSPar '%s': %s" % (str(request), str(e))) if response.status != 200: from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError( "Unable to create the OSPar '%s': Status %s, Error %s" % (str(request), response.status, str(response.data))) oci_par = response.data if oci_par is None: from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError( "Unable to create the preauthenticated request!") created_datetime = oci_par.time_created.replace( tzinfo=_datetime.timezone.utc) expires_datetime = oci_par.time_expires.replace( tzinfo=_datetime.timezone.utc) # the URI returned by OCI does not include the server. We need # to get the server based on the region of this bucket url = _get_object_url_for_region(bucket["region"], oci_par.access_uri) # get the checksum for this URL - used to validate the close # request from Acquire.ObjectStore import OSPar as _OSPar from Acquire.ObjectStore import OSParRegistry as _OSParRegistry url_checksum = _OSPar.checksum(url) driver_details = {"driver": "oci", "bucket": bucket["bucket_name"], "created_datetime": created_datetime, "par_id": oci_par.id, "par_name": oci_par.name} par = _OSPar(url=url, encrypt_key=encrypt_key, key=oci_par.object_name, expires_datetime=expires_datetime, is_readable=readable, is_writeable=writeable, driver_details=driver_details) _OSParRegistry.register(par=par, url_checksum=url_checksum, details_function=_get_driver_details_from_par, cleanup_function=cleanup_function) return par
def create_par(bucket, encrypt_key, key=None, readable=True, writeable=False, duration=3600, cleanup_function=None): """Create a pre-authenticated request for the passed bucket and key (if key is None then the request is for the entire bucket). This will return a OSPar object that will contain a URL that can be used to access the object/bucket. If writeable is true, then the URL will also allow the object/bucket to be written to. PARs are time-limited. Set the lifetime in seconds by passing in 'duration' (by default this is one hour) Args: bucket (dict): Bucket to create OSPar for encrypt_key (PublicKey): Public key to encrypt PAR key (str, default=None): Key readable (bool, default=True): If bucket is readable writeable (bool, default=False): If bucket is writeable duration (int, default=3600): Duration OSPar should be valid for in seconds cleanup_function (function, default=None): Cleanup function to be passed to PARRegistry Returns: OSPar: Pre-authenticated request for the bucket """ from Acquire.Crypto import PublicKey as _PublicKey if not isinstance(encrypt_key, _PublicKey): from Acquire.Client import PARError raise PARError("You must supply a valid PublicKey to encrypt the " "returned OSPar") is_bucket = (key is None) if writeable: method = "PUT" elif readable: method = "GET" else: from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError("Unsupported permissions model for OSPar!") try: # get the UTC datetime when this OSPar should expire from Acquire.ObjectStore import get_datetime_now as _get_datetime_now created_datetime = _get_datetime_now() expires_datetime = _get_datetime_now() + _datetime.timedelta( seconds=duration) bucket_obj = bucket["bucket"] if is_bucket: url = bucket_obj.generate_signed_url( version='v4', expiration=expires_datetime, method=method) else: blob = bucket_obj.blob(key) url = blob.generate_signed_url(version='v4', expiration=expires_datetime, method=method) except Exception as e: # couldn't create the preauthenticated request from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError("Unable to create the OSPar '%s': %s" % (key, str(e))) if url is None: from Acquire.ObjectStore import ObjectStoreError raise ObjectStoreError("Unable to create the signed URL!") # get the checksum for this URL - used to validate the close # request from Acquire.ObjectStore import OSPar as _OSPar from Acquire.ObjectStore import OSParRegistry as _OSParRegistry url_checksum = _OSPar.checksum(url) bucket_name = bucket["bucket_name"] driver_details = { "driver": "gcp", "bucket": bucket_name, "created_datetime": created_datetime } par = _OSPar(url=url, encrypt_key=encrypt_key, key=key, expires_datetime=expires_datetime, is_readable=readable, is_writeable=writeable, driver_details=driver_details) _OSParRegistry.register(par=par, url_checksum=url_checksum, details_function=_get_driver_details_from_par, cleanup_function=cleanup_function) return par
def create_par(bucket, encrypt_key, key=None, readable=True, writeable=False, duration=3600, cleanup_function=None): """Create a pre-authenticated request for the passed bucket and key (if key is None then the request is for the entire bucket). This will return a PAR object that will contain a URL that can be used to access the object/bucket. If writeable is true, then the URL will also allow the object/bucket to be written to. PARs are time-limited. Set the lifetime in seconds by passing in 'duration' (by default this is one hour). Note that you must pass in a public key that will be used to encrypt this PAR. This is necessary as the PAR grants access to anyone who can decrypt the URL """ from Acquire.Crypto import PublicKey as _PublicKey if not isinstance(encrypt_key, _PublicKey): from Acquire.Client import PARError raise PARError("You must supply a valid PublicKey to encrypt the " "returned PAR") if key is not None: if not _os.path.exists("%s/%s._data" % (bucket, key)): from Acquire.Client import PARError raise PARError( "The object '%s' in bucket '%s' does not exist!" % (key, bucket)) elif not _os.path.exists(bucket): from Acquire.Client import PARError raise PARError("The bucket '%s' does not exist!" % bucket) url = "file://%s" % bucket if key: url = "%s/%s" % (url, key) # get the time this PAR was created from Acquire.ObjectStore import get_datetime_now as _get_datetime_now created_datetime = _get_datetime_now() # get the UTC datetime when this PAR should expire expires_datetime = created_datetime + \ _datetime.timedelta(seconds=duration) # mimic limitations of OCI - cannot have a bucket PAR with # read permissions! if (key is None) and readable: from Acquire.Client import PARError raise PARError( "You cannot create a Bucket PAR that has read permissions " "due to a limitation in the underlying platform") from Acquire.ObjectStore import OSPar as _OSPar from Acquire.ObjectStore import OSParRegistry as _OSParRegistry url_checksum = _OSPar.checksum(url) driver_details = { "driver": "testing_objstore", "bucket": bucket, "created_datetime": created_datetime } par = _OSPar(url=url, key=key, encrypt_key=encrypt_key, expires_datetime=expires_datetime, is_readable=readable, is_writeable=writeable, driver_details=driver_details) _OSParRegistry.register(par=par, url_checksum=url_checksum, details_function=_get_driver_details_from_par, cleanup_function=cleanup_function) return par