def _get_identity_service(identity_url=None): """Function to return the identity service for the system""" if identity_url is None: identity_url = _get_identity_url() from Acquire.Service import is_running_service as _is_running_service if _is_running_service(): from Acquire.Service import get_trusted_service \ as _get_trusted_service return _get_trusted_service(service_url=identity_url, service_type='identity') from Acquire.Client import LoginError try: from Acquire.Client import Wallet as _Wallet wallet = _Wallet() service = wallet.get_service(service_url=identity_url, service_type="identity") except Exception as e: from Acquire.Service import exception_to_string raise LoginError("Have not received the identity service info from " "the identity service at '%s'\n\nCAUSE: %s" % (identity_url, exception_to_string(e))) if not service.can_identify_users(): raise LoginError( "You can only use a valid identity service to log in! " "The service at '%s' is a '%s'" % (identity_url, service.service_type())) return service
def service(self): """Return the service that holds the File/Drive behind this location """ if self.is_null(): return None from Acquire.Service import get_trusted_service \ as _get_trusted_service return _get_trusted_service(service_uid=self.service_uid())
def compute_service(self): """Return the compute service that will be used to actually perform the calculation associated with this work TODO - will eventually have to choose which compute service to use. Currently returning the compute service that is at the same root URL as this access service """ from Acquire.Service import get_this_service as _get_this_service from Acquire.Service import get_trusted_service as _get_trusted_service service = _get_this_service() compute_url = service.canonical_url().replace("access", "compute") return _get_trusted_service(service_url=compute_url)
def storage_service(self): """Return the storage service that will be used to store the output data associated with this work TODO - will eventually have to choose which storage service to use. Currently returning the storage service that is at the same root URL as this access service """ from Acquire.Service import get_this_service as _get_this_service from Acquire.Service import get_trusted_service as _get_trusted_service service = _get_this_service() storage_url = service.canonical_url().replace("access", "storage") return _get_trusted_service(service_url=storage_url)
def service(self): """Return the service that created this OSPar Returns: Service: Service object that created this OSPar """ service_url = self.service_url() if service_url is not None: from Acquire.Service import get_trusted_service \ as _get_trusted_service print(service_url) return _get_trusted_service(service_url=service_url) else: return None
def get_session_info(identity_url, session_uid, scope=None, permissions=None): """Call the identity_url to obtain information about the specified login session_uid. Optionally limit the scope and permissions for which these certs would be valid """ from Acquire.Service import get_trusted_service as _get_trusted_service service = _get_trusted_service(identity_url) args = {"session_uid": session_uid} if scope is not None: args["scope"] = scope if permissions is not None: args["permissions"] = permissions response = service.call_function(function="get_session_info", args=args) try: del response["status"] except: pass try: del response["message"] except: pass from Acquire.Crypto import PublicKey as _PublicKey for key in response.keys(): if key in ["public_key", "public_certificate"]: response[key] = _PublicKey.from_data(response[key]) return response
def _get_user_public_cert(self, scope=None, permissions=None): """Internal function that returns the public certificate of the user who signed this authorisation. This will check that the authorisation was not signed after the user logged out, as well as validating the services that provide the user session keys etc. """ must_fetch = False try: if scope != self._scope or permissions != self._permissions: must_fetch = True except: must_fetch = True if self._pubcert is not None: if not must_fetch: try: return self._pubcert except: pass try: testing_key = self._testing_key except: testing_key = None if testing_key is not None: if not self._is_testing: raise PermissionError( "You cannot pass a test key to a non-testing " "Authorisation") return testing_key # we need to get the public signing key for this session from Acquire.Service import get_trusted_service \ as _get_trusted_service from Acquire.ObjectStore import get_datetime_now \ as _get_datetime_now try: identity_service = _get_trusted_service(self._identity_url) except: raise PermissionError( "Unable to verify the authorisation as we do not trust " "the identity service at %s" % self._identity_url) if not identity_service.can_identify_users(): raise PermissionError( "Cannot verify an Authorisation that does not use a " "valid identity service") if identity_service.uid() != self._identity_uid: raise PermissionError( "Cannot auth_once this Authorisation as the actual UID of " "the identity service at '%s' (%s) does not match " "the UID of the service that signed this authorisation " "(%s)" % (self._identity_url, identity_service.uid(), self._identity_uid)) response = identity_service.get_session_info( session_uid=self._session_uid, scope=scope, permissions=permissions) try: user_uid = response["user_uid"] except: pass if self._user_uid != user_uid: raise PermissionError( "Cannot verify the authorisation as there is " "disagreement over the UID of the user who signed " "the authorisation. %s versus %s" % (self._user_uid, user_uid)) try: logout_datetime = _string_to_datetime(response["logout_datetime"]) except: logout_datetime = None if logout_datetime: # the user has logged out from this session - ensure that # the authorisation was created before the user logged out if logout_datetime < self.signature_time(): raise PermissionError( "This authorisation was signed after the user logged " "out. This means that the authorisation is not valid. " "Please log in again and create a new authorisation.") from Acquire.Crypto import PublicKey as _PublicKey pubcert = _PublicKey.from_data(response["public_cert"]) self._pubcert = pubcert self._scope = scope self._permissions = permissions return pubcert
def get_trusted_registry_service(registry_uid=None, service_uid=None, service_url=None): """Return the trusted service info for the registry with specified registry_uid, or get any trusted registry service using either 'service_uid' or 'service_url' as a starting hint to locate a suitable registry """ if service_uid is not None: # for the moment, just try to get one registry. Eventually we should # try to get several in case this one is down registry_uid = get_primary_registry_uid(service_uid) return get_trusted_registry_service(registry_uid=registry_uid) if service_url is not None: if service_url.find(".") != -1: # try the main acquire registry first return get_trusted_registry_service(registry_uid="a0-a0") else: # this must be testing... return get_trusted_registry_service(registry_uid="Z9-Z9") if registry_uid is None: raise PermissionError( "You must specify one of registry_uid, service_uid " "or service_url") from Acquire.Service import get_trusted_service as _get_trusted_service try: registry_service = _get_trusted_service(service_uid=registry_uid, autofetch=False) except: registry_service = None if registry_service is not None: if not registry_service.is_registry_service(): from Acquire.Service import ServiceError raise ServiceError("The requested service (%s) for %s is NOT a " "registry service!" % (registry_service, registry_uid)) if registry_service.uid() != registry_uid: from Acquire.Service import ServiceError raise ServiceError( "Disagreement of UID (%s) is NOT the right registry service!" % registry_service) # everything is ok - we have seen this registry before return registry_service # boostrapping from Acquire.Registry import get_registry_details \ as _get_registry_details details = _get_registry_details(registry_uid) from Acquire.Service import call_function as _call_function from Acquire.Service import Service as _Service from Acquire.Crypto import get_private_key as _get_private_key from Acquire.Crypto import PrivateKey as _PrivateKey from Acquire.Crypto import PublicKey as _PublicKey from Acquire.ObjectStore import bytes_to_string as _bytes_to_string from Acquire.ObjectStore import string_to_bytes as _string_to_bytes privkey = _get_private_key(key="registry") pubkey = _PublicKey.from_data(details["public_key"]) pubcert = _PublicKey.from_data(details["public_certificate"]) # ask the registry to return to us their latest details - use # a challenge-response to make sure that the response is # properly returned challenge = _PrivateKey.random_passphrase() encrypted_challenge = _bytes_to_string(pubkey.encrypt(challenge)) args = { "challenge": encrypted_challenge, "fingerprint": pubkey.fingerprint() } result = _call_function(service_url=details["canonical_url"], function=None, args=args, args_key=pubkey, response_key=privkey, public_cert=pubcert) if result["response"] != challenge: from Acquire.Service import ServiceError raise ServiceError( "The requested service (%s) failed to respond to the challenge!" % registry_service) registry_service = _Service.from_data(result["service_info"]) if not registry_service.is_registry_service(): from Acquire.Service import ServiceError raise ServiceError( "The requested service (%s) is NOT a registry service!" % registry_service) if registry_service.uid() != details["uid"]: from Acquire.Service import ServiceError raise ServiceError( "Disagreement of UID (%s) is NOT the right registry service!" % registry_service) # ok - we've got the registry - add this to the set of # trusted services so that we don't need to bootstrap from # the registry details again from Acquire.Service import trust_service as _trust_service _trust_service(registry_service) return registry_service