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