Пример #1
0
    def to_data(self):
        """Return this credit note as a dictionary that can be
           encoded to JSON

           Returns:
                dict: Dictionary of object to be encoded to JSON
        """
        data = {}

        if not self.is_null():
            from Acquire.ObjectStore import datetime_to_string \
                as _datetime_to_string

            data["account_uid"] = self._account_uid
            data["debit_account_uid"] = self._debit_account_uid
            data["uid"] = self._uid
            data["debit_note_uid"] = self._debit_note_uid
            data["datetime"] = _datetime_to_string(self._datetime)
            data["value"] = str(self._value)
            data["is_provisional"] = self._is_provisional

            if self._is_provisional:
                data["receipt_by"] = _datetime_to_string(self._receipt_by)

        return data
Пример #2
0
    def _get_message(self, resource=None, matched_resource=False):
        """Internal function that is used to generate the message for
           the resource that is signed. This message
           encodes information about the user and identity service that
           signed the message, as well as the resource. This helps
           prevent tamporing with the data in this authorisation.

           If 'matched_resource' is True then this will return the
           message based on the previously-verified resource
           (as we have already determined that the user knows what
           the resource is)
        """
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string

        if matched_resource:
            resource = self._last_verified_resource

        if resource is None:
            return "%s|%s|%s|%s" % (self._user_uid, self._session_uid,
                                    self._identity_uid,
                                    _datetime_to_string(self._auth_datetime))
        else:
            return "%s|%s|%s|%s|%s" % (
                self._user_uid, self._session_uid, self._identity_uid,
                str(resource), _datetime_to_string(self._auth_datetime))
Пример #3
0
    def register(par, url_checksum, details_function, cleanup_function=None):
        """Register the passed PAR, passing in the checksum of
           the PAR's secret URL (so we can verify the close),
           and optionally supplying a cleanup_function that is
           called when the PAR is closed. The passed 'details_function'
           should be used to extract the object-store driver-specific
           details from the PAR and convert them into a dictionary.
           The signature should be;

           driver_details = details_function(par)
        """
        from Acquire.Service import is_running_service as _is_running_service

        if not _is_running_service():
            return

        from Acquire.Service import get_service_account_bucket \
            as _get_service_account_bucket

        from Acquire.ObjectStore import OSPar as _OSPar

        from Acquire.ObjectStore import ObjectStore as _ObjectStore
        from Acquire.ObjectStore import Function as _Function
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string

        if par is None:
            return

        if not isinstance(par, _OSPar):
            raise TypeError("You can only register pars of type PAR")

        if par.is_null():
            return

        data = {}
        data["par"] = par.to_data()

        if details_function is None:
            data["driver_details"] = par._driver_details
        else:
            data["driver_details"] = details_function(par)

        data["url_checksum"] = url_checksum

        if cleanup_function is not None:
            if not isinstance(cleanup_function, _Function):
                cleanup_function = _Function(cleanup_function)

            data["cleanup_function"] = cleanup_function.to_data()

        expire_string = _datetime_to_string(par.expires_when())

        key = "%s/uid/%s/%s" % (_registry_key, par.uid(), expire_string)

        bucket = _get_service_account_bucket()
        _ObjectStore.set_object_from_json(bucket, key, data)

        key = "%s/expire/%s/%s" % (_registry_key, expire_string, par.uid())
        _ObjectStore.set_object_from_json(bucket, key, par.uid())
Пример #4
0
    def to_key(self):
        """Return this transaction encoded to a key"""
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string

        return "%s/%s/%s" % (_datetime_to_string(self._datetime), self._uid,
                             TransactionInfo.encode(
                                 code=self._code,
                                 value=self._value,
                                 receipted_value=self._receipted_value))
Пример #5
0
 def __str__(self):
     if self.is_null():
         return "PAR::null"
     elif not self.is_authorised():
         return "PAR::unauthorised"
     else:
         from Acquire.ObjectStore import datetime_to_string \
             as _datetime_to_string
         return "PAR( %s, %s, expires %s )" % (
             self._location.to_string(), self._aclrule,
             _datetime_to_string(self._expires_datetime))
Пример #6
0
 def fingerprint(self):
     """Return a fingerprint that can be used to show that
        the user authorised the request to create this PAR
     """
     if self.is_null():
         return None
     else:
         from Acquire.ObjectStore import datetime_to_string \
             as _datetime_to_string
         return "%s:%s:%s" % (self._location.fingerprint(),
                              self._aclrule.fingerprint(),
                              _datetime_to_string(self._expires_datetime))
Пример #7
0
    def close(par):
        """Close the passed PAR. This will remove the registration
           for the PAR and will also call the associated
           cleanup_function (if any)
        """
        from Acquire.Service import is_running_service as _is_running_service

        if not _is_running_service():
            return

        from Acquire.Service import get_service_account_bucket \
            as _get_service_account_bucket

        from Acquire.ObjectStore import OSPar as _OSPar

        from Acquire.ObjectStore import ObjectStore as _ObjectStore
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string
        from Acquire.ObjectStore import Function as _Function

        if par is None:
            return

        if not isinstance(par, _OSPar):
            raise TypeError("You can only close OSPar objects!")

        if par.is_null():
            return

        expire_string = _datetime_to_string(par.expires_when())

        bucket = _get_service_account_bucket()

        key = "%s/expire/%s/%s" % (_registry_key, expire_string, par.uid())
        try:
            _ObjectStore.delete_object(bucket=bucket, key=key)
        except:
            pass

        key = "%s/uid/%s/%s" % (_registry_key, par.uid(), expire_string)

        try:
            data = _ObjectStore.take_object_from_json(bucket=bucket, key=key)
        except:
            data = None

        if data is None:
            # this PAR has already been closed
            return

        if "cleanup_function" in data:
            cleanup_function = _Function.from_data(data["cleanup_function"])
            cleanup_function(par=par)
Пример #8
0
    def to_data(self):
        """Return this DebitNote as a dictionary that can be encoded as json

               Returns:
                    dict: Dictionary to be converted to JSON

        """
        data = {}

        if not self.is_null():
            from Acquire.ObjectStore import datetime_to_string \
                as _datetime_to_string
            data["transaction"] = self._transaction.to_data()
            data["account_uid"] = self._account_uid
            data["authorisation"] = self._authorisation.to_data()
            data["is_provisional"] = self._is_provisional
            data["datetime"] = _datetime_to_string(self._datetime)
            data["uid"] = self._uid

            if self._is_provisional:
                data["receipt_by"] = _datetime_to_string(self._receipt_by)

        return data
Пример #9
0
def _get_driver_details_from_par(par):
    from Acquire.ObjectStore import datetime_to_string \
        as _datetime_to_string

    import copy as _copy
    details = _copy.copy(par._driver_details)

    if details is None:
        return {}
    else:
        # fix any non-string/number objects
        details["created_datetime"] = _datetime_to_string(
            details["created_datetime"])

    return details
Пример #10
0
    def to_data(self):
        """Return a json-serialisable dictionary of this PAR"""
        if self.is_null():
            return None

        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string

        data = {}

        data["location"] = self._location.to_data()
        data["aclrule"] = self._aclrule.to_data()
        data["expires_datetime"] = _datetime_to_string(self._expires_datetime)
        data["uid"] = self._uid

        return data
Пример #11
0
    def to_data(self):
        """Return a json-serialisable dictionary of this object"""
        data = {}

        if self.is_null():
            return data

        data["filename"] = str(self._filename)

        if self._uid is not None:
            data["uid"] = str(self._uid)

        if self._filesize is not None:
            data["filesize"] = self._filesize

        if self._checksum is not None:
            data["checksum"] = self._checksum

        if self._user_guid is not None:
            data["user_guid"] = self._user_guid

        if self._compression is not None:
            data["compression"] = self._compression

        try:
            acl = self._acl
        except:
            acl = None

        if acl is not None:
            data["acl"] = acl.to_data()

        try:
            aclrules = self._aclrules
        except:
            aclrules = None

        if aclrules is not None:
            data["aclrules"] = aclrules.to_data()

        if self._datetime is not None:
            from Acquire.ObjectStore import datetime_to_string \
                as _datetime_to_string
            data["datetime"] = _datetime_to_string(self._datetime)

        return data
Пример #12
0
    def to_data(self, passphrase=None):
        """Return a json-serialisable dictionary that contains all data
           for this object

           Args:
                passphrase (str, default=None): Passphrase to use to
                encrypt OSPar
           Returns:
                dict: JSON serialisable dictionary
        """
        data = {}

        if self._url is None:
            return data

        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string
        from Acquire.ObjectStore import bytes_to_string \
            as _bytes_to_string

        data["url"] = _bytes_to_string(self._url)
        data["uid"] = self._uid
        data["key"] = self._key
        data["expires_datetime"] = _datetime_to_string(self._expires_datetime)
        data["is_readable"] = self._is_readable
        data["is_writeable"] = self._is_writeable

        try:
            if self._service_url is not None:
                data["service_url"] = self._service_url
        except:
            pass

        try:
            privkey = self._privkey
        except:
            privkey = None

        if privkey is not None:
            if passphrase is not None:
                data["privkey"] = privkey.to_data(passphrase)

        # note that we don't save the driver details as these
        # are stored separately on the service

        return data
Пример #13
0
def _get_driver_details_from_par(par):
    """Internal function used to get the OCI driver details from the
       passed OSPar (pre-authenticated request)

       Args:
            par (OSPar): PAR holding details
        Args:
            dict: Dictionary holding OCI driver details
    """
    from Acquire.ObjectStore import datetime_to_string \
        as _datetime_to_string

    import copy as _copy
    details = _copy.copy(par._driver_details)

    if details is None:
        return {}
    else:
        # fix any non-string/number objects
        details["created_datetime"] = _datetime_to_string(
                                        details["created_datetime"])

    return details
Пример #14
0
    def lock(self, timeout=None, lease_time=None):
        """Lock the mutex, blocking until the mutex is held, or until
           'timeout' seconds have passed. If we time out, then an exception is
           raised. The lock is held for a maximum of 'lease_time' seconds.

           Args:
                timeout (int): Number of seconds to block
                lease_time (int): Number of seconds to hold the lock
           Returns:
                None
        """
        # if the user does not provide a timeout, then we will set a timeout
        # to 10 seconds
        if timeout is None:
            timeout = 10.0
        else:
            timeout = float(timeout)

        # if the user does not provide a lease_time, then we will set a
        # default of only 10 seconds
        if lease_time is None:
            lease_time = 10.0
        else:
            lease_time = float(lease_time)

        from Acquire.ObjectStore import get_datetime_now as _get_datetime_now
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string
        from Acquire.ObjectStore import string_to_datetime \
            as _string_to_datetime
        from Acquire.ObjectStore import ObjectStore as _ObjectStore

        if self.is_locked():
            # renew the lease - if there is less than a second remaining
            # on the lease then unlock and then lock again from scratch
            now = _get_datetime_now()

            if (now > self._end_lease) or (now - self._end_lease).seconds < 1:
                self.fully_unlock()
                self.lock(timeout, lease_time)
            else:
                self._end_lease = now + _datetime.timedelta(seconds=lease_time)

                self._lockstring = "%s{}%s" % (
                    self._secret, _datetime_to_string(self._end_lease))

                _ObjectStore.set_string_object(self._bucket, self._key,
                                               self._lockstring)

                self._is_locked += 1

            return

        now = _get_datetime_now()
        endtime = now + _datetime.timedelta(seconds=timeout)

        # This is the first time we are trying to get a lock
        while now < endtime:
            # does anyone else hold the lock?
            try:
                holder = _ObjectStore.get_string_object(
                    self._bucket, self._key)
            except:
                holder = None

            is_held = True

            if holder is None:
                is_held = False
            else:
                end_lease = _string_to_datetime(holder.split("{}")[-1])
                if now > end_lease:
                    # the lease from the other holder has expired :-)
                    is_held = False

            if not is_held:
                # no-one holds this mutex - try to hold it now
                self._end_lease = now + _datetime.timedelta(seconds=lease_time)

                self._lockstring = "%s{}%s" % (
                    self._secret, _datetime_to_string(self._end_lease))

                _ObjectStore.set_string_object(self._bucket, self._key,
                                               self._lockstring)

                holder = _ObjectStore.get_string_object(
                    self._bucket, self._key)
            else:
                self._lockstring = None

            if holder == self._lockstring:
                # it looks like we are the holder - read and write again
                # just to make sure
                holder = _ObjectStore.get_string_object(
                    self._bucket, self._key)

                if holder == self._lockstring:
                    # write again just to make sure
                    _ObjectStore.set_string_object(self._bucket, self._key,
                                                   self._lockstring)

                    holder = _ObjectStore.get_string_object(
                        self._bucket, self._key)

            if holder == self._lockstring:
                # we have read and written our secret to the object store
                # three times. While a race condition is still possible,
                # I'd hope it is now highly unlikely - we now hold the mutex
                self._is_locked = 1
                return

            # only try the lock 4 times a second
            _time.sleep(0.25)

            now = _get_datetime_now()

        from Acquire.ObjectStore import MutexTimeoutError
        raise MutexTimeoutError("Cannot acquire a mutex lock on the "
                                "key '%s'" % self._key)
Пример #15
0
    def read(self, spend, resource, receipt_by):
        """Read the cheque - this will read the cheque to return the
           decrypted contents. This will only work if this function
           is called on the accounting service that will cash the
           cheque, if the signature on the cheque matches the
           service that is authorised to cash the cheque, and
           if the passed resource matches the resource
           encoded in the cheque. If this is all correct, then the
           returned dictionary will contain;

           {"recipient_url": The URL of the service which was sent the cheque,
            "recipient_key_fingerprint": Verified fingerprint of the service
                                         key that signed this cheque
            "spend": The amount authorised by this cheque,
            "uid": The unique ID for this cheque,
            "resource": String that identifies the resource this cheque will
                        be used to pay for,
            "account_uid": UID of the account from which funds will be drawn
            "authorisation" : Verified authorisation from the user who
                              says they own the account for the spend
            "receipt_by" : Time when we must receipt the cheque, or
                           we will lose the money
           }

           You must pass in the spend you want to draw from the cheque,
           a string representing the resource this cheque will
           be used to pay for, and the time by which you promise to receipt
           the cheque after cashing

           Args:
                spend (Decimal): Amount authorised by cheque
                resource (str): Resource to pay for
                receipt_by (datetime): Time cheque must be receipted
                by
           Returns:
                dict: Dictionary described above

        """

        if self._cheque is None:
            raise PaymentError("You cannot read a null cheque")

        from Acquire.ObjectStore import string_to_decimal \
            as _string_to_decimal
        from Acquire.ObjectStore import string_to_datetime \
            as _string_to_datetime
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string
        from Acquire.Service import get_this_service as _get_this_service

        spend = _string_to_decimal(spend)
        resource = str(resource)
        receipt_by = _string_to_datetime(receipt_by)

        service = _get_this_service(need_private_access=True)

        # get the cheque data - this may have been signed
        try:
            cheque_data = _json.loads(self._cheque["signed_data"])
        except:
            cheque_data = self._cheque

        # decrypt the cheque's data - only possible on the accounting service
        cheque_data = service.decrypt_data(cheque_data)

        # the date comprises the user-authorisation that acts as a
        # signature that the user wrote this cheque, and the info
        # for the cheque to say how it is valid
        from Acquire.Identity import Authorisation as _Authorisation
        auth = _Authorisation.from_data(cheque_data["authorisation"])
        info = cheque_data["info"]

        # the json.dumps version is the resource used to verify
        # the above authorisation
        auth_resource = info

        # validate that the user authorised this cheque
        try:
            auth.verify(resource=info)
        except Exception as e:
            raise PaymentError(
                "The user's signature/authorisation for this cheque "
                "is not valid! ERROR: %s" % str(e))

        info = _json.loads(info)

        # the user signed this cheque :-)
        info["authorisation"] = auth

        # check the signature if one was needed
        try:
            recipient_url = info["recipient_url"]
        except:
            recipient_url = None

        if recipient_url:
            # the recipient was specified - verify that we trust
            # the recipient, and that they have signed the cheque
            recipient_service = service.get_trusted_service(
                                            service_url=recipient_url)
            recipient_service.verify_data(self._cheque)
            info["recipient_key_fingerprint"] = self._cheque["fingerprint"]

        # validate that the item signature is correct
        try:
            cheque_resource = info["resource"]
        except:
            cheque_resource = None

        if cheque_resource is not None:
            if resource != resource:
                raise PaymentError(
                    "Disagreement over the resource for which "
                    "this cheque has been signed")

        info["resource"] = resource
        info["auth_resource"] = auth_resource

        try:
            max_spend = info["max_spend"]
            del info["max_spend"]
        except:
            max_spend = None

        if max_spend is not None:
            max_spend = _string_to_decimal(max_spend)

            if max_spend < spend:
                raise PaymentError(
                    "The requested spend (%s) exceeds the authorised "
                    "maximum value of the cheque" % (spend))

        info["spend"] = spend

        try:
            expiry_date = info["expiry_date"]
            del expiry_date["expiry_date"]
        except:
            expiry_date = None

        if expiry_date is not None:
            expiry_date = _string_to_datetime(expiry_date)

            # validate that the cheque will not have expired
            # when we receipt it
            from Acquire.ObjectStore import get_datetime_now \
                as _get_datetime_now
            now = _get_datetime_now()

            if now > receipt_by:
                raise PaymentError(
                    "The time when you promised to receipt the cheque "
                    "has already passed!")

            if receipt_by > expiry_date:
                raise PaymentError(
                    "The cheque will have expired after you plan to "
                    "receipt it!: %s versus %s" %
                    (_datetime_to_string(receipt_by),
                     _datetime_to_string(expiry_date)))

        info["receipt_by"] = receipt_by

        return info
Пример #16
0
    def cash(self, spend, resource, receipt_within=3600):
        """Cash this cheque, specifying how much to be cashed,
           and the resource that will be paid for
           using this cheque. This will send the cheque to the
           accounting service (if we trust that accounting service).
           The accounting service will check that the cheque is valid,
           and the signature of the item is correct. It will then
           withdraw 'spend' funds from the account that signed the
           cheque, returning valid CreditNote(s) that can be trusted
           to show that the funds exist.

           If 'receipt_within' is set, then the CreditNotes will
           be automatically cancelled if they are not
           receipted within 'receipt_within' seconds

           It is your responsibility to receipt the note for
           the actual valid incurred once the service has been
           delivered, thereby actually transferring the cheque
           funds into your account (on that accounting service)

           This returns a list of the CreditNote(s) that were
           cashed from the cheque

           Args:
                spend (Decimal): Value to withdraw
                resource (str): Resource to spend value on
                receipt_within (datetime, default=3600): Time to receipt
                the cashing of this cheque by
           Returns:
                list: List of CreditNotes

        """
        if self._cheque is None:
            raise PaymentError("You cannot cash a null cheque!")

        # sign the cheque to show we have seen it
        from Acquire.Service import get_this_service as _get_this_service
        service = _get_this_service(need_private_access=True)
        self._cheque = service.sign_data(self._cheque)

        # get the trusted accounting service that will honour the cheque
        accounting_service = self.accounting_service()

        # when do we guarantee to receipt the credit notes by?
        from Acquire.ObjectStore import get_datetime_future \
            as _get_datetime_future
        receipt_by = _get_datetime_future(receipt_within)

        # which account should the money be paid into?
        account_uid = service.service_user_account_uid(
                                accounting_service=accounting_service)

        # next - send the cheque to the accounting service to
        # show that we know the item_id and want to cash it
        from Acquire.ObjectStore import decimal_to_string \
            as _decimal_to_string
        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string
        from Acquire.ObjectStore import string_to_list \
            as _string_to_list

        result = accounting_service.call_function(
            function="cash_cheque",
            args={"cheque": self.to_data(),
                  "spend": _decimal_to_string(spend),
                  "resource": str(resource),
                  "account_uid": account_uid,
                  "receipt_by": _datetime_to_string(receipt_by)})

        credit_notes = None

        try:
            from Acquire.Accounting import CreditNote as _CreditNote
            credit_notes = _string_to_list(result["credit_notes"],
                                           _CreditNote)
        except Exception as e:
            raise PaymentError(
                "Attempt to cash the cheque has not resulted in a "
                "valid CreditNote? Error = %s" % str(e))

        total_cashed = 0

        for note in credit_notes:
            total_cashed = total_cashed + note.value()
            if note.account_uid() != account_uid:
                raise PaymentError(
                    "The cashed cheque is paying into the wrong account! "
                    "%s. It should be going to %s" %
                    (note.account_uid(), account_uid))

        if total_cashed != spend:
            raise PaymentError(
                "The value of the cheque (%s) does not match the total value "
                "of the credit note(s) returned (%s)" % (spend, total_cashed))

        return credit_notes
Пример #17
0
    def write(account=None, resource=None,
              recipient_url=None, max_spend=None,
              expiry_date=None):
        """Create and return a cheque that can be used at any point
           in the future to authorise a transaction. If 'recipient_url'
           is supplied, then only the service with the matching
           URL can 'cash' the cheque (it will need to sign the cheque
           before sending it to the accounting service). If 'max_spend'
           is specified, then the cheque is only valid up to that
           maximum spend. Otherwise, it is valid up to the maximum
           daily spend limit (or other limits) of the account. If
           'expiry_date' is supplied then this cheque is valid only
           before the supplied datetime. If 'resource' is
           supplied then this cheque is only valid to pay for the
           specified resource (this should be a string that everyone
           agrees represents the resource in question). Note that
           this cheque is for a future transaction. We do not check
           to see if there are sufficient funds now, and this does
           not affect the account. If there are insufficient funds
           when the cheque is cashed (or it breaks spending limits)
           then the cheque will bounce.

           Args:
                account (Account, default=None): Account to use to write
                cheque
                resource (str, default=None): Define the resource to pay for
                recipient_url (str, default=None): URL of service to use
                max_spend (Decimal, default=None): Limit of cheque
                expiry_date (datetime, default=None): Cheque's expiry date
        """

        from Acquire.Client import Account as _Account

        if not isinstance(account, _Account):
            raise TypeError("You must pass a valid Acquire.Client.Account "
                            "object to write a cheque...")

        if max_spend is not None:
            from Acquire.ObjectStore import decimal_to_string \
                as _decimal_to_string
            max_spend = _decimal_to_string(max_spend)

        if expiry_date is not None:
            from Acquire.ObjectStore import datetime_to_string \
                as _datetime_to_string
            expiry_date = _datetime_to_string(expiry_date)

        if recipient_url is not None:
            recipient_url = str(recipient_url)

        from Acquire.ObjectStore import create_uuid as _create_uuid
        from Acquire.Identity import Authorisation as _Authorisation

        info = _json.dumps({"recipient_url": recipient_url,
                            "max_spend": max_spend,
                            "expiry_date": expiry_date,
                            "uid": _create_uuid(),
                            "resource": str(resource),
                            "account_uid": account.uid()})

        auth = _Authorisation(user=account.user(), resource=info)

        data = {"info": info, "authorisation": auth.to_data()}

        cheque = Cheque()

        cheque._cheque = account.accounting_service().encrypt_data(data)
        cheque._accounting_service_url = \
            account.accounting_service().canonical_url()

        return cheque
Пример #18
0
    def download(self, filename=None, version=None,
                 dir=None, force_par=False):
        """Download this file into the local directory
           the local directory, or 'dir' if specified,
           calling the file 'filename' (or whatever it is called
           on the Drive if not specified). If a local
           file exists with this name, then a new, unique filename
           will be used. This returns the local filename of the
           downloaded file (with full absolute path)

           Note that this only downloads files for which you
           have read-access. If the file is not readable then
           an exception is raised and nothing is returned

           If 'version' is specified then download a specific version
           of the file. Otherwise download the version associated
           with this file object
        """
        if self.is_null():
            raise PermissionError("Cannot download a null File!")

        if self._creds is None:
            raise PermissionError("We have not properly opened the file!")

        if filename is None:
            filename = self._metadata.name()

        drive_uid = self._metadata.drive().uid()

        from Acquire.Client import create_new_file as \
            _create_new_file

        if self._creds.is_user():
            privkey = self._creds.user().session_key()
        else:
            from Acquire.Crypto import get_private_key as _get_private_key
            privkey = _get_private_key("parkey")

        args = {"drive_uid": drive_uid,
                "filename": self._metadata.name(),
                "encryption_key": privkey.public_key().to_data()}

        if self._creds.is_user():
            from Acquire.Client import Authorisation as _Authorisation
            authorisation = _Authorisation(
                        resource="download %s %s" % (drive_uid,
                                                     self._metadata.name()),
                        user=self._creds.user())
            args["authorisation"] = authorisation.to_data()
        elif self._creds.is_par():
            par = self._creds.par()
            par.assert_valid()
            args["par_uid"] = par.uid()
            args["secret"] = self._creds.secret()

        if force_par:
            args["force_par"] = True

        if version is not None:
            from Acquire.ObjectStore import datetime_to_string \
                as _datetime_to_string
            args["version"] = _datetime_to_string(version)
        elif self._metadata.version() is not None:
            args["version"] = self._metadata.version()

        storage_service = self._creds.storage_service()

        response = storage_service.call_function(
                                function="download", args=args)

        from Acquire.Client import FileMeta as _FileMeta
        filemeta = _FileMeta.from_data(response["filemeta"])

        if "filedata" in response:
            # we have already downloaded the file to 'filedata'
            filedata = response["filedata"]

            from Acquire.ObjectStore import string_to_bytes \
                as _string_to_bytes
            filedata = _string_to_bytes(response["filedata"])
            del response["filedata"]

            # validate that the size and checksum are correct
            filemeta.assert_correct_data(filedata)

            if filemeta.is_compressed():
                # uncompress the data
                from Acquire.Client import uncompress as _uncompress
                filedata = _uncompress(
                                inputdata=filedata,
                                compression_type=filemeta.compression_type())

            # write the data to the specified local file...
            filename = _create_new_file(filename=filename, dir=dir)
            with open(filename, "wb") as FILE:
                FILE.write(filedata)
                FILE.flush()
        elif "download_par" in response:
            from Acquire.ObjectStore import OSPar as _OSPar
            filename = _create_new_file(filename=filename, dir=dir)
            par = _OSPar.from_data(response["download_par"])
            par.read(privkey).get_object_as_file(filename)
            par.close(privkey)

            # validate that the size and checksum are correct
            filemeta.assert_correct_data(filename=filename)

            # uncompress the file if desired
            if filemeta.is_compressed():
                from Acquire.Client import uncompress as _uncompress
                _uncompress(inputfile=filename,
                            outputfile=filename,
                            compression_type=filemeta.compression_type())

        elif "downloader" in response:
            from Acquire.Client import ChunkDownloader as _ChunkDownloader
            downloader = _ChunkDownloader.from_data(response["downloader"],
                                                    privkey=privkey,
                                                    service=storage_service)

            filename = downloader.download(filename=filename, dir=dir)

        filemeta._copy_credentials(self._metadata)
        self._metadata = filemeta

        return filename
Пример #19
0
    def to_data(self):
        """Return a data version (dictionary) of this LoginSession
           that can be serialised to json
        """
        if self.is_null():
            return {}

        from Acquire.ObjectStore import datetime_to_string \
            as _datetime_to_string

        data = {}
        data["uid"] = self._uid
        data["username"] = self._username
        data["request_datetime"] = _datetime_to_string(self._request_datetime)
        data["public_certificate"] = self._pubcert.to_data()
        data["status"] = self._status

        if self._pubkey is not None:
            data["public_key"] = self._pubkey.to_data()

        try:
            data["login_datetime"] = _datetime_to_string(self._login_datetime)
        except:
            pass

        try:
            data["logout_datetime"] = _datetime_to_string(
                self._logout_datetime)
        except:
            pass

        try:
            data["ipaddr"] = self._ipaddr
        except:
            pass

        try:
            data["hostname"] = self._hostname
        except:
            pass

        try:
            data["login_message"] = self._login_message
        except:
            pass

        try:
            data["scope"] = self._scope
        except:
            pass

        try:
            data["permissions"] = self._permissions
        except:
            pass

        try:
            data["user_uid"] = self._user_uid
        except:
            pass

        try:
            data["device_uid"] = self._device_uid
        except:
            pass

        return data