Exemplo n.º 1
0
    def register(self, par, authorisation, secret=None):
        """Register the passed par, which is authorised using the
           passed authorisation. If the authorisation is correct
           this this will return the URL of the PAR
        """
        from Acquire.Client import PAR as _PAR
        from Acquire.Client import Authorisation as _Authorisation

        if not isinstance(par, _PAR):
            raise TypeError("The par must be type PAR")

        # create a new UID for this PAR
        from Acquire.ObjectStore import create_uid as _create_uid
        uid = _create_uid()
        par._set_uid(uid)

        if par.expired():
            raise PermissionError("The passed PAR has already expired!")

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

        identifiers = authorisation.verify(resource="create_par %s" %
                                           par.fingerprint(),
                                           return_identifiers=True)

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

        if secret is not None and len(secret) > 0:
            from Acquire.Crypto import Hash
            secret = Hash.multi_md5(uid, secret)
        else:
            secret = None

        import json as _json
        data = {
            "par": par.to_data(),
            "identifiers": _json.dumps(identifiers),
            "secret": secret
        }

        key = "%s/%s" % (_par_root, uid)

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

        return uid
Exemplo n.º 2
0
    def __init__(self, drive_uid=None, file_uid=None):
        """Create a new ChunkDowloader that downloads the specified
           file from the specified drive
        """
        self._uid = None
        self._drive_uid = None
        self._file_uid = None
        self._service = None

        self._next_index = None
        self._last_filename = None
        self._downloaded_filename = None
        self._FILE = None

        if drive_uid is not None:
            self._drive_uid = str(drive_uid)
            self._file_uid = str(file_uid)
            from Acquire.Crypto import PrivateKey as _PrivateKey
            self._secret = _PrivateKey.random_passphrase()

            from Acquire.ObjectStore import create_uid as _create_uid
            self._uid = _create_uid(short_uid=True)
Exemplo n.º 3
0
    def __init__(self, image=None, input=None, resources=None):
        """Construct the request specifying the container image 'image'
           that contains the software used for the calculation,
           and the location of the input files 'input' that will be
           downloaded and run using this container.

           You can also optionally supply the compute resources
           (resources) that will be needed to run this job
        """
        super().__init__()

        self._uid = None
        self._image = str(image)
        self._resources = resources

        self._input = input

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

            from Acquire.ObjectStore import create_uid as _create_uid
            self._uid = _create_uid()
Exemplo n.º 4
0
    def __init__(self, url=None, key=None,
                 encrypt_key=None,
                 expires_datetime=None,
                 is_readable=False,
                 is_writeable=False,
                 driver_details=None):
        """Construct an OSPar result by passing in the URL at which the
           object can be accessed, the UTC datetime when this expires,
           whether this is readable or writeable, and
           the encryption key to use to encrypt the OSPar.

           You can optionally pass in the key for the object in the
           object store that
           this provides access to. If this is not supplied, then an
           entire bucket is accessed). If 'is_readable', then read-access
           has been granted, while if 'is_writeable' then write
           access has been granted.

           Otherwise no access is possible.

           driver_details is provided by the machinery that creates
           the OSPar, and supplies extra details that are used by the
           driver to create, register and manage OSPars... You should
           not do anything with driver_details yourself
        """
        service_url = None

        if url is None:
            is_readable = True
            self._uid = None
        else:
            from Acquire.Crypto import PublicKey as _PublicKey
            from Acquire.Crypto import PrivateKey as _PrivateKey

            if isinstance(encrypt_key, _PrivateKey):
                encrypt_key = encrypt_key.public_key()

            if not isinstance(encrypt_key, _PublicKey):
                raise TypeError(
                    "You must supply a valid PublicKey to encrypt a OSPar")

            url = encrypt_key.encrypt(url)

            from Acquire.ObjectStore import create_uid as _create_uid
            self._uid = _create_uid()

            try:
                from Acquire.Service import get_this_service \
                    as _get_this_service
                service_url = _get_this_service().canonical_url()
            except:
                pass

        self._url = url
        self._key = key
        self._expires_datetime = expires_datetime
        self._service_url = service_url

        if driver_details is not None:
            if not isinstance(driver_details, dict):
                raise TypeError("The driver details must be a dictionary")

        self._driver_details = driver_details

        if is_readable:
            self._is_readable = True
        else:
            self._is_readable = False

        if is_writeable:
            self._is_writeable = True
        else:
            self._is_writeable = False

        if not (self._is_readable or self._is_writeable):
            from Acquire.Client import PARPermissionsError
            raise PARPermissionsError(
                "You cannot create a OSPar that has no read or write "
                "permissions!")
Exemplo n.º 5
0
    def get_drive(self, name, aclrules=None, autocreate=True):
        """Return the DriveMeta for the Drive that the user has
           called 'name'. If 'autocreate' is True then this
           drive is automatically created if it does not exist. Note
           that the '/' in the name will be interpreted as drive
           separators.
        """
        if self.is_null():
            raise PermissionError(
                "You cannot get a DriveInfo from a null UserDrives")

        # break the name into directory parts
        from Acquire.ObjectStore import string_to_filepath_parts \
            as _string_to_filepath_parts

        parts = _string_to_filepath_parts(name)

        # first get the root drive...
        root_name = parts[0]

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

        from Acquire.ObjectStore import string_to_encoded as _string_to_encoded

        encoded_name = _string_to_encoded(root_name)
        drive_name = root_name

        bucket = _get_service_account_bucket()

        drive_key = "%s/%s/%s" % (_drives_root, self._user_guid, encoded_name)

        try:
            drive_uid = _ObjectStore.get_string_object(bucket, drive_key)
        except:
            drive_uid = None

        if drive_uid is not None:
            from Acquire.Storage import DriveInfo as _DriveInfo
            drive = _DriveInfo(drive_uid=drive_uid,
                               is_authorised=self._is_authorised,
                               identifiers=self._identifiers)
        else:
            drive = None

        if drive is None:
            if self._is_authorised and autocreate:
                # create a new UID for the drive and write this to the
                # object store
                from Acquire.ObjectStore import create_uid as _create_uid

                drive_uid = _create_uid()

                drive_uid = _ObjectStore.set_ins_string_object(
                    bucket, drive_key, drive_uid)

                from Acquire.Storage import DriveInfo as _DriveInfo
                drive = _DriveInfo(drive_uid=drive_uid,
                                   identifiers=self._identifiers,
                                   is_authorised=self._is_authorised,
                                   aclrules=aclrules,
                                   autocreate=True)

        if drive is None:
            from Acquire.Storage import MissingDriveError
            raise MissingDriveError("There is no Drive called '%s' available" %
                                    name)

        container = []

        # now we have the drive, get the sub-drive in this drive...
        if len(parts) > 1:
            for subdrive in parts[1:]:
                container.append(drive.uid())
                drive_name = subdrive
                drive = self._get_subdrive(drive_uid=drive.uid(),
                                           name=drive_name,
                                           autocreate=autocreate)

                if drive is None:
                    from Acquire.Storage import MissingDriveError
                    raise MissingDriveError(
                        "There is no Drive called '%s' available" % name)

        from Acquire.Storage import DriveMeta as _DriveMeta

        drivemeta = _DriveMeta(name=drive_name,
                               uid=drive.uid(),
                               container=container,
                               aclrules=drive.aclrules())

        drivemeta.resolve_acl(identifiers=self._identifiers)

        return drivemeta
Exemplo n.º 6
0
    def write(account=None,
              resource=None,
              recipient=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.
        """

        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 is not None:
            from Acquire.Service import Service as _Service
            recipient_url = _Service.resolve(recipient)["service_url"]
        elif recipient_url is not None:
            from Acquire.Service import Service as _Service
            recipient_url = _Service.resolve(recipient_url)["service_url"]
        else:
            raise PermissionError(
                "You have to specify the recipient of the cheque!")

        from Acquire.ObjectStore import create_uid as _create_uid
        from Acquire.Identity import Authorisation as _Authorisation

        cheque_uid = _create_uid(include_date=True, short_uid=True)

        info = _json.dumps({
            "recipient_url": recipient_url,
            "max_spend": max_spend,
            "expiry_date": expiry_date,
            "uid": cheque_uid,
            "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