Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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
Beispiel #6
0
    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