예제 #1
0
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
예제 #2
0
    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())
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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
예제 #6
0
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
예제 #7
0
    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