Esempio n. 1
0
def create_account(user,
                   account_name,
                   description=None,
                   accounting_service=None,
                   accounting_url=None):
    """Create an account on the accounting service for the passed
        user, calling the account 'account_name' and optionally
        passing in an account description. Note that the user must
        have authorised the login

        Args:
            user (User): User to create account for
            account_name (str): Name of account to create
            accounting_service (Service, default=None): Accounting
            service on which to create account
            accounting_url (str, default=None): Accounting URL
        Returns:
            Account: New account
    """

    if accounting_service is None:
        service = _get_accounting_service(accounting_url)
    else:
        if not accounting_service.is_accounting_service():
            raise TypeError("You can only query account using "
                            "a valid accounting service")
        service = accounting_service

    if not user.is_logged_in():
        raise PermissionError(
            "You cannot create an account called '%s' for user "
            "'%s' as the user login has not been authenticated." %
            (account_name, user.name()))

    from Acquire.Client import Authorisation as _Authorisation
    authorisation = _Authorisation(user=user,
                                   resource="create_account %s" % account_name)

    args = {
        "account_name": str(account_name),
        "authorisation": authorisation.to_data()
    }

    if description is None:
        args["description"] = "Account '%s' for '%s'" % \
                                (str(account_name), user.name())
    else:
        args["description"] = str(description)

    result = service.call_function(function="create_account", args=args)

    account_uid = result["account_uid"]

    account = Account()
    account._account_name = account_name
    account._account_uid = account_uid
    account._user = user
    account._accounting_service = service

    return account
Esempio n. 2
0
    def logout(self):
        """Log out from the current session"""
        if self.is_logged_in() or self.is_logging_in():
            service = self.identity_service()

            args = {"session_uid": self._session_uid}

            if self.is_logged_in():
                from Acquire.Client import Authorisation as _Authorisation
                authorisation = _Authorisation(
                                    resource="logout %s" % self._session_uid,
                                    user=self)
                args["authorisation"] = authorisation.to_data()
            else:
                # we are not fully logged in so cannot generate an
                # authorisation for the logout
                from Acquire.ObjectStore import bytes_to_string \
                    as _bytes_to_string
                resource = "logout %s" % self._session_uid
                signature = self.signing_key().sign(resource)
                args["signature"] = _bytes_to_string(signature)

            result = service.call_function(function="logout", args=args)

            self._status = _LoginStatus.LOGGED_OUT

            return result
Esempio n. 3
0
    def refund(self, credit_note):
        """Refunds the passed credit note that contained a transfer of
           from another account to the passed account

           Args:
                credit_note (CreditNote): Credit note to refund
           Returns:
                TransactionRecord: Record of this transaction
        """
        if not self.is_logged_in():
            raise PermissionError("You cannot refund a credit note as the "
                                  "user has not yet logged in!")

        if credit_note.account_uid() != self.uid():
            raise ValueError(
                "You cannot refund a transaction from a different "
                "account! %s versus %s" % (credit_note.account_uid(),
                                           self.uid()))

        from Acquire.Client import Authorisation as _Authorisation
        from Acquire.Accounting import create_decimal as _create_decimal

        service = self.accounting_service()

        auth = _Authorisation(resource=self._account_uid, user=self._user)

        args = {"credit_note": credit_note.to_data(),
                "authorisation": auth.to_data()}

        result = service.call_function(function="refund", args=args)

        return result["transaction_record"]
Esempio n. 4
0
def _get_account_uids(user, accounting_service=None, accounting_url=None):
    """Return the names and UIDs of all of the accounts that belong
        to the passed user on the passed accounting_service

        Args:
            user (User): User for query
            accounting_service (Service, default=None): Accounting
            service to check
            accounting_url (str, default=None): Accounting URL

        Returns:
            list: Names and UIDs of accounts belonging to passed user
            on passed service
    """
    if accounting_service is None:
        service = _get_accounting_service(accounting_url)
    else:
        if not accounting_service.is_accounting_service():
            raise TypeError("You can only query accounts using "
                            "a valid accounting service")
        service = accounting_service

    if not user.is_logged_in():
        raise PermissionError(
            "You can only get information about about a user's accounts "
            "if they have authenticated their login")

    from Acquire.Client import Authorisation as _Authorisation
    auth = _Authorisation(user=user, resource="get_account_uids")
    args = {"authorisation": auth.to_data()}

    result = service.call_function(function="get_account_uids", args=args)

    return result["account_uids"]
Esempio n. 5
0
    def _refresh(self, force_update=False):
        """Refresh the current status of this account. This fetches
           the latest data, e.g. balance, limits etc. Note that this
           limits you to refreshing at most once every five seconds...

           Args:
                force_update (bool, default=False): Force the refresh
           Returns:
                None
        """
        if self.is_null():
            from Acquire.Accounting import create_decimal as _create_decimal
            from Acquire.Accounting import Balance as _Balance
            self._overdraft_limit = _create_decimal(0)
            self._balance = _Balance()
            return

        if force_update:
            should_refresh = True
        else:
            should_refresh = False

            if self._last_update is None:
                should_refresh = True
            else:
                should_refresh = (_datetime.datetime.now() -
                                  self._last_update).seconds > 5

        if not should_refresh:
            return

        if not self.is_logged_in():
            raise PermissionError(
                "You cannot get information about this account "
                "until after the owner has successfully authenticated.")

        from Acquire.Client import Authorisation as _Authorisation
        from Acquire.Accounting import create_decimal as _create_decimal

        service = self.accounting_service()

        auth = _Authorisation(resource="get_info %s" % self._account_uid,
                              user=self._user)

        args = {
            "authorisation": auth.to_data(),
            "account_name": self.name(),
            "account_uid": self.uid()
        }

        result = service.call_function(function="get_info", args=args)

        from Acquire.Accounting import Balance as _Balance
        self._balance = _Balance.from_data(result["balance"])
        self._overdraft_limit = _create_decimal(result["overdraft_limit"])
        self._description = result["description"]

        self._last_update = _datetime.datetime.now()
Esempio n. 6
0
    def perform(self, transaction, credit_account, is_provisional=False):
        """Tell this accounting service to apply the transfer described
           in 'transaction' from this account to the passed account. Note
           that the user must have logged into this account so that they
           have authorised this transaction. This returns the record
           of this transaction

           Args:
                transaction (Transaction): Transaction to perform
                credit_account (Account): Account to credit
                is_provisional (bool, default=False): Is transaction
                provisional
        """
        if not self.is_logged_in():
            raise PermissionError("You cannot transfer value from '%s' to "
                                  "'%s' because you have not authenticated "
                                  "the user who owns this account" %
                                  (str(self), str(credit_account)))

        from Acquire.Accounting import Transaction as _Transaction

        if not isinstance(transaction, _Transaction):
            raise TypeError("The passed transaction must be of type "
                            "Transaction")

        if not isinstance(credit_account, Account):
            raise TypeError("The passed credit account must be of type "
                            "Account")

        if transaction.is_null():
            return None

        from Acquire.Client import Authorisation as _Authorisation
        service = self.accounting_service()

        auth = _Authorisation(resource=transaction.fingerprint(),
                              user=self._user)

        if is_provisional:
            is_provisional = True
        else:
            is_provisional = False

        args = {
            "transaction": transaction.to_data(),
            "debit_account_uid": str(self.uid()),
            "credit_account_uid": str(credit_account.uid()),
            "is_provisional": is_provisional,
            "authorisation": auth.to_data()
        }

        result = service.call_function(function="perform", args=args)

        return result["transaction_records"]
Esempio n. 7
0
    def list_versions(self, include_metadata=False):
        """Return a list of all of the versions of this file.
           If 'include_metadata' is True then this will include
           the full metadata of every version
        """
        if self.is_null():
            return []

        if self._creds is None:
            raise PermissionError(
                "Cannot list versions of this file as it has not "
                "been properly opened")

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

        if include_metadata:
            include_metadata = True
        else:
            include_metadata = False

        filename = self._metadata.name()

        args = {"drive_uid": drive_uid,
                "include_metadata": include_metadata,
                "filename": filename}

        if self._creds.is_user():
            from Acquire.Client import Authorisation as _Authorisation
            authorisation = _Authorisation(
                                    resource="list_versions %s" % filename,
                                    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()

        storage_service = self._creds.storage_service()

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

        from Acquire.ObjectStore import string_to_list \
            as _string_to_list
        from Acquire.Storage import FileMeta as _FileMeta

        versions = _string_to_list(response["versions"], _FileMeta)

        for version in versions:
            version._copy_credentials(self._metadata)

        return versions
Esempio n. 8
0
    def chunk_download(self, filename=None, version=None,
                       dir=None):
        """Return a ChunkDownloader to download this file
           chunk-by-chunk
        """
        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()

        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(),
                "must_chunk": True}

        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()

        storage_service = self._creds.storage_service()

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

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

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

        return downloader
Esempio n. 9
0
def _get_drive(creds,
               name=None,
               drive_uid=None,
               aclrules=None,
               autocreate=True):
    """Return the drive called 'name' using the passed credentials. The name
       will default to 'main' if it is not set, and the drive will
       be created automatically is 'autocreate' is True and the
       drive does not exist. If the drive is created, it would
       be created with the passed aclrules, if specified
       (this will be user-owner-only if not specified)
    """
    storage_service = creds.storage_service()

    if drive_uid is None:
        if name is None:
            name = "main"
        else:
            name = str(name)

        if autocreate:
            autocreate = True
        else:
            autocreate = False
    else:
        name = None
        autocreate = False
        drive_uid = str(drive_uid)

    args = {"name": name, "autocreate": autocreate, "drive_uid": drive_uid}

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

    if creds.is_user():
        from Acquire.Client import Authorisation as _Authorisation
        authorisation = _Authorisation(resource="UserDrives",
                                       user=creds.user())
        args["authorisation"] = authorisation.to_data()
    elif creds.is_par():
        par = creds.par()
        par.assert_valid()
        args["par_uid"] = par.uid()
        args["secret"] = creds.secret()

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

    from Acquire.Client import DriveMeta as _DriveMeta

    return _create_drive(creds=creds,
                         metadata=_DriveMeta.from_data(response["drive"]))
Esempio n. 10
0
def deposit(user,
            value,
            description=None,
            account_name=None,
            accounting_service=None,
            accounting_url=None):
    """Tell the system to allow the user to deposit 'value' from
       their (real) financial account to the system accounts

       Args:
            user (User): User to authorise
            value (Decimal): Value to deposit
            description (str): Description of deposit
            accounting_service (Service, default=None): Accounting
            service to make deposit
            accounting_url (str): Accounting URl
       Returns:
            TODO - return value here

    """
    if accounting_service is None:
        service = _get_accounting_service(accounting_url)
    else:
        if not accounting_service.is_accounting_service():
            raise TypeError("You can only deposit funds using an "
                            "accounting service!")
        service = accounting_service

    if description is None:
        description = "Deposit"

    from Acquire.Accounting import Transaction as _Transaction
    transaction = _Transaction(value=value, description=description)

    from Acquire.Client import Authorisation as _Authorisation
    authorisation = _Authorisation(user=user,
                                   resource=transaction.fingerprint())

    args = {
        "authorisation": authorisation.to_data(),
        "transaction": transaction.to_data()
    }

    if account_name:
        args["account_name"] = str(account_name)

    result = service.call_function(function="deposit", args=args)

    return result
Esempio n. 11
0
    def list_files(self, dir=None, filename=None, include_metadata=False):
        """Return a list of the FileMetas of all of the files contained
           in this drive. If 'dir' is specified then list only the
           files that are contained in 'dir'. If 'filename' is specified
           then return only the files that match the passed filename
        """
        if self.is_null():
            return []

        from Acquire.ObjectStore import string_to_list as _string_to_list
        from Acquire.Storage import FileMeta as _FileMeta

        if include_metadata:
            include_metadata = True
        else:
            include_metadata = False

        args = {
            "drive_uid": self._metadata.uid(),
            "include_metadata": include_metadata
        }

        if dir is not None:
            args["dir"] = str(dir)

        if filename is not None:
            args["filename"] = str(filename)

        if self._creds.is_user():
            from Acquire.Client import Authorisation as _Authorisation
            authorisation = _Authorisation(resource="list_files",
                                           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()

        response = self.storage_service().call_function(function="list_files",
                                                        args=args)

        files = _string_to_list(response["files"], _FileMeta)

        for f in files:
            f._set_drive_metadata(self._metadata, self._creds)

        return files
Esempio n. 12
0
def _get_account_uid(user,
                     account_name,
                     accounting_service=None,
                     accounting_url=None):
    """Return the UID of the account called 'account_name' that
        belongs to passed user on the passed accounting_service

        Args:
            user (User): User for query
            account_name (str): Name of account
            accounting_service (Service, default=None): Accounting service
            to check
            accounting_url (str, default=None): Account URL
        Returns:
            str: UID of account named 'account_name'
    """
    if account_name is None:
        # return the UID of the default account for this user
        account_name = "main"

    if accounting_service is None:
        service = _get_accounting_service(accounting_url)
    else:
        if not accounting_service.is_accounting_service():
            raise TypeError("You can only query accounts using "
                            "a valid accounting service")
        service = accounting_service

    args = {"user_guid": user.guid(), "account_name": str(account_name)}

    if user.is_logged_in():
        from Acquire.Client import Authorisation as _Authorisation
        auth = _Authorisation(user=user, resource="get_account_uids")
        args["authorisation"] = auth.to_data()

    result = service.call_function(function="get_account_uids", args=args)

    account_uids = result["account_uids"]

    for account_uid in account_uids:
        if account_uids[account_uid] == account_name:
            return account_uid

    from Acquire.Client import AccountError
    raise AccountError("There is no account called '%s' for '%s'" %
                       (account_name, str(user)))
Esempio n. 13
0
    def set_cluster(cluster, authorisation=None, passphrase=None, user=None):
        """Function used to set the single compute cluster that is
           connected to this compute service. This must be authorised
           by an admin user of this compute service
        """
        if not isinstance(cluster, Cluster):
            raise TypeError("The cluster must be type Cluster")

        resource = "set_cluster %s" % cluster.fingerprint()

        from Acquire.Client import Authorisation as _Authorisation
        if Cluster._is_running_service():
            from Acquire.Service import get_this_service as _get_this_service

            service = _get_this_service(need_private_access=True)

            if authorisation is not None:
                if not isinstance(authorisation, _Authorisation):
                    raise TypeError(
                        "The authorisation must be type Authorisation")

                service.assert_admin_authorised(authorisation, resource)
            else:
                # we are rotating keys, so check the passphrase against
                # the old passphrase
                cluster = Cluster.get_cluster()
                cluster.verify_passphrase(passphrase=passphrase,
                                          resource="set_cluster")

            from Acquire.ObjectStore import ObjectStore as _ObjectStore
            from Acquire.Service import get_service_account_bucket \
                as _get_service_account_bucket

            bucket = _get_service_account_bucket()
            key = "compute/cluster"
            _ObjectStore.set_object_from_json(bucket, key, cluster.to_data())
        else:
            authorisation = _Authorisation(user=user, resource=resource)
            compute_service = cluster.compute_service()

            args = {"authorisation": authorisation.to_data(),
                    "cluster": cluster.to_data()}

            compute_service.call_function(function="set_cluster", args=args)
Esempio n. 14
0
    def _list_drives(creds, drive_uid=None):
        """Return a list of all of the DriveMetas of the drives accessible
           at the top-level using the passed credentials, or that are
           sub-drives of the drive with UID 'drive_uid'
        """
        from Acquire.Client import StorageCreds as _StorageCreds
        if not isinstance(creds, _StorageCreds):
            raise TypeError("The passed creds must be type StorageCreds")

        args = {}

        if creds.is_user():
            if drive_uid is not None:
                drive_uid = str(drive_uid)

            from Acquire.Client import Authorisation as _Authorisation
            authorisation = _Authorisation(resource="UserDrives",
                                           user=creds.user())

            args = {"authorisation": authorisation.to_data()}
        elif creds.is_par():
            par = creds.par()
            par.assert_valid()
            args["par"] = par.to_data()
            args["secret"] = creds.secret()

        if drive_uid is not None:
            args["drive_uid"] = str(drive_uid)

        storage_service = creds.storage_service()

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

        from Acquire.ObjectStore import string_to_list as _string_to_list
        from Acquire.Client import DriveMeta as _DriveMeta

        drives = _string_to_list(response["drives"], _DriveMeta)

        for drive in drives:
            drive._creds = creds

        return drives
Esempio n. 15
0
    def receipt(self, credit_note, receipted_value=None):
        """Receipt the passed credit note that contains a request to
           transfer value from another account to the passed account

           Args:
                credit_note (CreditNote): CreditNote to use to create
                receipt
                receipted_value (Decimal, default=None): Receipted value
            Returns:
                TransactionRecord: Record of this transaction
        """
        if not self.is_logged_in():
            raise PermissionError("You cannot receipt a credit note as the "
                                  "user has not yet logged in!")

        if credit_note.account_uid() != self.uid():
            raise ValueError(
                "You cannot receipt a transaction from a different "
                "account! %s versus %s" %
                (credit_note.account_uid(), self.uid()))

        from Acquire.Client import Authorisation as _Authorisation
        from Acquire.Accounting import create_decimal as _create_decimal

        service = self.accounting_service()

        auth = _Authorisation(resource=self._account_uid, user=self._user)

        args = {
            "credit_note": credit_note.to_data(),
            "authorisation": auth.to_data()
        }

        if receipted_value is not None:
            args["receipted_value"] = str(_create_decimal(receipted_value))

        result = service.call_function(function="receipt", args=args)

        return result["transaction_record"]
Esempio n. 16
0
 def authorise(self, resource):
     """Create an authorisation for the specified resource"""
     from Acquire.Client import Authorisation as _Authorisation
     return _Authorisation(user=self, resource=resource)
Esempio n. 17
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
Esempio n. 18
0
    def chunk_upload(self, aclrules=None):
        """Start a chunk-upload of a new version of this file. This
           will return a chunk-uploader that can be used to upload
           a file chunk-by-chunk
        """
        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!")

        from Acquire.Client import Authorisation as _Authorisation
        from Acquire.ObjectStore import OSPar as _OSPar
        from Acquire.Client import FileMeta as _FileMeta

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

        args = {"filename": uploaded_name,
                "drive_uid": drive_uid}

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

        if self._creds.is_user():
            authorisation = _Authorisation(
                        resource="chunk_upload %s" % uploaded_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()
        else:
            raise PermissionError(
                "Either a logged-in user or valid PAR must be provided!")

        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["encryption_key"] = privkey.public_key().to_data()

        # will eventually need to authorise payment...
        storage_service = self._creds.storage_service()

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

        filemeta = _FileMeta.from_data(response["filemeta"])

        filemeta._set_drive_metadata(self._metadata._drive_metadata,
                                     self._creds)

        self._metadata = filemeta

        from Acquire.Client import ChunkUploader as _ChunkUploader
        return _ChunkUploader.from_data(response["uploader"],
                                        privkey=privkey,
                                        service=storage_service)
Esempio n. 19
0
    def __init__(self,
                 location=None,
                 user=None,
                 aclrule=None,
                 expires_datetime=None):
        """Construct a PAR for the specified location,
           authorised by the passed user, giving permissions
           according to the passed 'aclrule' (default is
           ACLRule.reader()).

           The passed 'expires_datetime' is the time at which
           this PAR will expire (by default within 24 hours)
        """
        self._location = None
        self._uid = None
        self._expires_datetime = None

        if location is None:
            return

        from Acquire.Client import Location as _Location
        if not isinstance(location, _Location):
            raise TypeError("The location must be type Location")

        if location.is_null():
            return

        from Acquire.Client import User as _User
        if not isinstance(user, _User):
            raise TypeError("The user must be type User")

        if not user.is_logged_in():
            raise PermissionError("The passed User must be logged in!")

        from Acquire.Client import ACLRule as _ACLRule

        if aclrule is None:
            aclrule = _ACLRule.reader()
        elif not isinstance(aclrule, _ACLRule):
            raise TypeError("The aclrule must be type ACLRule")

        if expires_datetime is None:
            from Acquire.ObjectStore import get_datetime_future \
                as _get_datetime_future
            expires_datetime = _get_datetime_future(days=1)
        else:
            from Acquire.ObjectStore import datetime_to_datetime \
                as _datetime_to_datetime
            expires_datetime = _datetime_to_datetime(expires_datetime)

        self._location = location
        self._expires_datetime = expires_datetime
        self._aclrule = aclrule

        from Acquire.Client import Authorisation as _Authorisation
        auth = _Authorisation(user=user,
                              resource="create_par %s" % self.fingerprint())

        from Acquire.Crypto import PrivateKey as _PrivateKey
        self._secret = _PrivateKey.random_passphrase()

        args = {
            "authorisation": auth.to_data(),
            "par": self.to_data(),
            "secret": self._secret
        }

        service = location.service()

        result = service.call_function(function="create_par", args=args)

        self._set_uid(result["par_uid"])
Esempio n. 20
0
    def upload(self, filename, force_par=False, aclrules=None):
        """Upload 'filename' as the new version of this file"""
        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!")

        from Acquire.Client import Authorisation as _Authorisation
        from Acquire.ObjectStore import OSPar as _OSPar
        from Acquire.Client import FileMeta as _FileMeta
        from Acquire.Storage import FileHandle as _FileHandle

        local_cutoff = None

        if force_par:
            # only upload using a OSPar
            local_cutoff = 0

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

        filehandle = _FileHandle(filename=filename,
                                 remote_filename=uploaded_name,
                                 drive_uid=drive_uid,
                                 aclrules=aclrules,
                                 local_cutoff=local_cutoff)

        try:
            args = {"filehandle": filehandle.to_data()}

            if self._creds.is_user():
                authorisation = _Authorisation(
                            resource="upload %s" % filehandle.fingerprint(),
                            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()
            else:
                raise PermissionError(
                    "Either a logged-in user or valid PAR must be provided!")

            if not filehandle.is_localdata():
                # we will need to upload against a OSPar, so need to tell
                # the service how to encrypt the OSPar...
                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["encryption_key"] = privkey.public_key().to_data()

            # will eventually need to authorise payment...
            storage_service = self._creds.storage_service()

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

            filemeta = _FileMeta.from_data(response["filemeta"])

            # if this was a large file, then we will receive a OSPar back
            # which must be used to upload the file
            if not filehandle.is_localdata():
                par = _OSPar.from_data(response["upload_par"])
                par.write(privkey).set_object_from_file(
                                        filehandle.local_filename())
                par.close(privkey)

            filemeta._set_drive_metadata(self._metadata._drive_metadata,
                                         self._creds)

            return filemeta
        except:
            # ensure that any temporary files are removed
            filehandle.__del__()
            raise