def register(username, password, identity_url=None, service=None): """Request to register a new user with the specified username one the identity service running at 'identity_url', using the supplied 'password'. This will return a QR code that you must use immediately to add this user on the identity service to a QR code generator """ if service is not None: from Acquire.Service import Service as _Service service = _Service.resolve(service, fetch=True)["service"] elif identity_url is not None: from Acquire.Service import Service as _Service service = _Service.resolve(identity_url, fetch=True)["service"] else: service = _get_default_service() from Acquire.Client import Credentials as _Credentials encoded_password = _Credentials.encode_password( identity_uid=service.uid(), password=password) args = {"username": username, "password": encoded_password} result = service.call_function(function="register", args=args) try: provisioning_uri = result["provisioning_uri"] except: from Acquire.Client import UserError raise UserError("Cannot register the user '%s' on " "the identity service at '%s'!" % (username, identity_url)) # return a QR code for the provisioning URI result = {} result["provisioning_uri"] = provisioning_uri try: import re otpsecret = re.search(r"secret=([\w\d+]+)&issuer", provisioning_uri).groups()[0] result["otpsecret"] = otpsecret except: pass try: from Acquire.Client import create_qrcode as _create_qrcode result["qrcode"] = _create_qrcode(provisioning_uri) except: pass return result
def __init__(self, service=None, service_url=None, service_uid=None, service_type=None): """Construct the service that is accessed at the remote URL 'service_url'. This will fetch and return the details of the remote service. This wrapper is a chameleon class, and will transform into the class type of the fetched service, e.g. service = Acquire.Client.Service("https://identity_service_url") service.__class__ == Acquire.Identity.IdentityService """ if service is not None: from Acquire.Service import Service as _Service service = _Service.resolve(service, fetch=True)["service"] else: try: from Acquire.Client import Wallet as _Wallet service = _Wallet().get_service(service_url=service_url, service_uid=service_uid, service_type=service_type) except Exception as e: self._failed = True raise e from copy import copy as _copy self.__dict__ = _copy(service.__dict__) self.__class__ = service.__class__
def _get_default_service(): """Return the default identity service""" global _default_service if _default_service is None: from Acquire.Service import Service as _Service _default_service = _Service.resolve("fn.acquire-aaai.com/t/identity", fetch=True)["service"] return _default_service
def _related_service(self, service_type): # TODO: Allow the user to specify their preferred services url = self.identity_service_url() if not url.endswith("identity"): raise ValueError("No default accounting service set for this user") from Acquire.Service import Service as _Service url = _rreplace(url, "identity", service_type) return _Service.resolve(url)["service"]
def __init__(self, username=None, service=None, identity_url=None, identity_uid=None, scope=None, permissions=None, auto_logout=True): """Construct the user with specified 'username', who will login to the identity service at specified URL 'identity_url', or with UID 'identity_uid'. You can optionally request a user with a limited scope or limited permissions. Service lookup will be using you wallet. By default, the user will logout when this object is destroyed. Prevent this behaviour by setting auto_logout to False """ self._username = username self._status = _LoginStatus.EMPTY self._identity_service = None self._scope = scope self._permissions = permissions if service is not None: from Acquire.Service import Service as _Service s = _Service.resolve(service, fetch=False) self._identity_url = s["service_url"] self._identity_uid = s["service_uid"] self._identity_service = s["service"] elif (identity_uid is None) and (identity_url is None): service = _get_default_service() self._identity_url = service.canonical_url() self._identity_uid = service.uid() self._identity_service = service else: if identity_url: self._identity_url = identity_url if identity_uid: self._identity_uid = identity_uid else: self._identity_uid = None self._user_uid = None if auto_logout: self._auto_logout = True else: self._auto_logout = False
def identity_service(self): """Return the identity service info object for the identity service used to validate the identity of this user """ if self._identity_service is not None: return self._identity_service from Acquire.Service import Service as _Service service = _Service.resolve(service_url=self._identity_url, service_uid=self._identity_uid, fetch=True)["service"] self._identity_service = service self._identity_url = service.canonical_url() self._identity_uid = service.uid() return self._identity_service
def __init__(self, name=None, drive_uid=None, user=None, service=None, creds=None, aclrules=None, cheque=None, max_size=None, autocreate=True): """Construct a handle to the drive that the passed user calls 'name' on the passed storage service. If 'autocreate' is True and the user is logged in then this will automatically create the drive if it doesn't exist already """ self._metadata = None self._creds = None if user is not None: from Acquire.Client import StorageCreds as _StorageCreds from Acquire.Service import Service as _Service if service is None: service = user.storage_service() else: service = _Service.resolve(service, fetch=True)["service"] creds = _StorageCreds(user=user, service=service) if creds is not None: from Acquire.Client import StorageCreds as _StorageCreds if not isinstance(creds, _StorageCreds): raise TypeError("creds must be type StorageCreds") drive = _get_drive(creds=creds, name=name, drive_uid=drive_uid, aclrules=aclrules, autocreate=autocreate) from copy import copy as _copy self.__dict__ = _copy(drive.__dict__)
def refetch_trusted_service(service): """Refetch the trusted service 'service'. This will refetch the keys for this service from the registry. This is sometimes needed if we lose the chain of keys to the service (e.g. if the service admin resets the service) """ from Acquire.Service import Service as _Service from Acquire.Registry import get_trusted_registry_service \ as _get_trusted_registry_service s = _Service.resolve(service, fetch=False) registry = _get_trusted_registry_service(service_uid=service.uid()) clear_services_cache() service = registry.get_service(service_uid=s["service_uid"], service_url=s["service_url"]) from Acquire.Service import trust_service as _trust_service _trust_service(service) return service
def _set_default_service(service): """Set the defalt identity service to 'service'""" global _default_service from Acquire.Service import Service as _Service _default_service = _Service.resolve(service, fetch=True)["service"]
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