Beispiel #1
0
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if not self.is_identity_service():
                raise IdentityServiceError(
                    "Cannot construct an IdentityService from "
                    "a service which is not an identity service!")
        else:
            _Service.__init__(self)
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if not self.is_accounting_service():
                raise AccountingServiceError(
                    "Cannot construct an AccountingService from "
                    "a service which is not an accounting service!")
        else:
            _Service.__init__(self)
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if not self.is_access_service():
                from Acquire.Access import AccessServiceError
                raise AccessServiceError(
                    "Cannot construct an AccessService from "
                    "a service which is not an access service!")
        else:
            _Service.__init__(self)
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if not self.is_compute_service():
                from Acquire.Compute import ComputeServiceError
                raise ComputeServiceError(
                    "Cannot construct a ComputeService from "
                    "a service which is not an compute service!")
        else:
            _Service.__init__(self)
Beispiel #5
0
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if self.service_type() != "hugs":
                from hugs.Service import HugsServiceError

                raise HugsServiceError(
                    "Cannot construct a HugsService from a service which is not a hugs service!"
                )
        else:
            _Service.__init__(self)
Beispiel #6
0
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if not self.is_storage_service():
                from Acquire.Storage import StorageServiceError
                raise StorageServiceError(
                    "Cannot construct an StorageService from "
                    "a service which is not an storage service!")
        else:
            _Service.__init__(self)
            self._storage_compartment_id = None
Beispiel #7
0
    def __init__(self, other=None):
        if isinstance(other, _Service):
            from copy import copy as _copy
            self.__dict__ = _copy(other.__dict__)

            if not self.is_registry_service():
                from Acquire.Registry import RegistryServiceError
                raise RegistryServiceError(
                    "Cannot construct a RegistryService from "
                    "a service which is not a registry service!")
        else:
            _Service.__init__(self)
Beispiel #8
0
    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
Beispiel #9
0
def _refresh_this_service_keys_and_certs(service_info, service_password):
    from Acquire.Service import Service as _Service
    service = _Service.from_data(service_info, service_password)

    if service._uid == "STAGE1":
        return service_info

    if not service.should_refresh_keys():
        return service_info

    oldkeys = service.dump_keys(include_old_keys=False)

    # now write the old keys to storage
    from Acquire.ObjectStore import ObjectStore as _ObjectStore
    from Acquire.ObjectStore import Mutex as _Mutex
    from Acquire.Service import get_service_account_bucket as \
        _get_service_account_bucket

    bucket = _get_service_account_bucket()
    key = "%s/oldkeys/%s" % (_service_key, oldkeys["datetime"])
    _ObjectStore.set_object_from_json(bucket, key, oldkeys)

    # now write the pointers from fingerprint to file...
    for fingerprint in oldkeys.keys():
        if fingerprint not in ["datetime", "encrypted_passphrase"]:
            _ObjectStore.set_string_object(
                bucket,
                "%s/oldkeys/fingerprints/%s" % (_service_key, fingerprint),
                key)

    # generate new keys
    last_update = service.last_key_update()
    service.refresh_keys()

    # now lock the object store so that we are the only function
    # that can write the new keys to global state
    m = _Mutex(key=service.uid(), bucket=bucket)

    service_data = _ObjectStore.get_object_from_json(bucket, _service_key)
    service_info = _Service.from_data(service_data)

    if service_info.last_key_update() == last_update:
        # no-one else has beaten us - write the updated keys to global state
        _ObjectStore.set_object_from_json(bucket, _service_key,
                                          service.to_data(service_password))

    m.unlock()

    return service_data
Beispiel #10
0
def get_this_service(need_private_access=False):
    """Return the service info object for this service. If private
       access is needed then this will decrypt and access the private
       keys and signing certificates, which is slow if you just need
       the public certificates.
    """
    assert_running_service()

    from Acquire.Service import MissingServiceAccountError

    try:
        service_info = _get_this_service_data()
    except MissingServiceAccountError:
        raise
    except Exception as e:
        raise MissingServiceAccountError(
            "Unable to read the service info from the object store! : %s" %
            str(e))

    service_password = None

    if need_private_access:
        service_password = _get_service_password()

    try:
        from Acquire.Service import Service as _Service
        if service_password:
            service = _Service.from_data(service_info, service_password)
        else:
            service = _Service.from_data(service_info)

    except Exception as e:
        raise MissingServiceAccountError(
            "Unable to create the ServiceAccount object: %s %s" %
            (e.__class__, str(e)))

    if service.should_refresh_keys():
        if service_password is None:
            service_password = _get_service_password()

        service_info = _refresh_this_service_keys_and_certs(
            service_info, service_password)

        if need_private_access:
            return _Service.from_data(service_info, service_password)
        else:
            return _Service.from_data(service_info)
    else:
        return service
Beispiel #11
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()

    privkey = _PrivateKey()
    response = _call_function(identity_url, response_key=privkey)

    try:
        service = _Service.from_data(response["service_info"])
    except:
        raise LoginError("Have not received the identity service info from "
                         "the identity service at '%s' - got '%s'" %
                         (identity_url, response))

    if not service.is_identity_service():
        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()))

    if identity_url != service.service_url():
        service.update_service_url(identity_url)

    return service
Beispiel #12
0
def _get_access_service(access_url=None):
    """Function to return the access service for the system"""
    if access_url is None:
        access_url = _get_access_url()

    privkey = _PrivateKey()
    response = _call_function(access_url, response_key=privkey)

    try:
        service = _Service.from_data(response["service_info"])
    except:
        raise LoginError("Have not received the access service info from "
                         "the access service at '%s' - got '%s'" %
                         (access_url, response))

    if not service.is_access_service():
        raise LoginError(
            "You can only use a valid access service to access resources! "
            "The service at '%s' is a '%s'" %
            (access_url, service.service_type()))

    if service.service_url() != access_url:
        service.update_service_url(access_url)

    return service
Beispiel #13
0
 def from_data(data, password=None):
     """Deserialise this object from the passed data. This will
        only deserialise the private key and private certificate
        if the password is supplied
     """
     from Acquire.Service import Service as _Service
     return _Service.from_data(data, password)
Beispiel #14
0
    def __init__(self, other=None):
        if isinstance(other, _Service):
            self.__dict__ = _copy(other.__dict__)

            if not self.is_storage_service():
                from Acquire.Storage import StorageServiceError
                raise StorageServiceError(
                    "Cannot construct an StorageService from "
                    "a service which is not an storage service!")

            # the storage service must define the ID for the compartment
            # in which user data will be stored
            self._storage_compartment_id = _os.getenv("STORAGE_COMPARTMENT")
        else:
            _Service.__init__(self)
            self._storage_compartment_id = None
Beispiel #15
0
    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 run(args):
    """Call this function to register a new service with this registry"""

    service = Service.from_data(args["service"])
    challenge = string_to_bytes(args["challenge"])
    fingerprint = args["fingerprint"]

    try:
        force_new_uid = args["force_new_uid"]
    except:
        force_new_uid = False

    if force_new_uid:
        force_new_uid = True

    # respond to the challenge from the service to be registered
    this_service = get_this_service(need_private_access=True)
    key = this_service.get_key(fingerprint)
    response = key.decrypt(challenge)

    # ok - we can respond to its challenge, so now challenge
    # it, and if it passes, register the service
    registry = Registry()
    service_uid = registry.register_service(service=service,
                                            force_new_uid=force_new_uid)

    return {"service_uid": service_uid,
            "response": response}
Beispiel #17
0
    def _get_service(self, service_url):
        """Return the service data for the passed service"""
        try:
            return self._service_info[service_url]
        except:
            pass

        # can we read this from a file?
        service_file = "%s/certs_%s" % (
            ServiceWallet._wallet_dir(),
            _base64.b64encode(service_url.encode("utf-8")).decode("utf-8"))

        try:
            with open(service_file, "rb") as FILE:
                service_info = _Service.from_data(
                    _unpack_arguments(FILE.read()))
                self._service_info[service_url] = service_info
                return service_info
        except:
            pass

        try:
            key = _PrivateKey()
            response = _call_function(service_url, response_key=key)
            service = _Service.from_data(response["service_info"])
        except Exception as e:
            service = None

            if str(e).find(
                    "You haven't yet created the service account for "
                    "this service. Please create an account first") != -1:
                return None

            raise LoginError("Error connecting to the service %s: Error = %s" %
                             (service, str(e)))

        if service is None:
            raise LoginError("Error connecting to the service %s. "
                             "Has it been setup?" % service_url)

        self._service_info[service_url] = service

        # save this for future reference
        with open(service_file, "wb") as FILE:
            FILE.write(_pack_arguments(service.to_data()))

        return service
Beispiel #18
0
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
Beispiel #19
0
def run(args):
    """This function is used to request access to a bucket for
       data in the object store. The user can request read-only
       or read-write access. Access is granted based on a permission
       list
    """

    status = 0
    message = None

    access_token = None

    user_uuid = args["user_uuid"]
    identity_service_url = args["identity_service"]

    # log into the central access account
    bucket = login_to_service_account()

    # is the identity service supplied by the user one that we trust?
    identity_service = Service.from_data(
        ObjectStore.get_object_from_json(bucket,
                                         "services/%s" % identity_service_url))

    if not identity_service:
        raise RequestBucketError(
            "You cannot request a bucket because "
            "this access service does not know or trust your supplied "
            "identity service (%s)" % identity_service_url)

    if not identity_service.is_identity_service():
        raise RequestBucketError(
            "You cannot request a bucket because "
            "the passed service (%s) is not an identity service. It is "
            "a %s" % (identity_service_url, identity_service.service_type()))

    # Since we trust this identity service, we can ask it to give us the
    # public certificate and signing certificate for this user.
    key = PrivateKey()

    response = call_function(identity_service_url,
                             "get_user_keys",
                             args_key=identity_service.public_key(),
                             response_key=key,
                             user_uuid=user_uuid)

    status = 0
    message = "Success: Status = %s" % str(response)

    return_value = create_return_value(status, message)

    if access_token:
        return_value["access_token"] = access_token

    return return_value
Beispiel #20
0
    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"]
Beispiel #21
0
def test_service_object(tmpdir_factory):
    bucket = tmpdir_factory.mktemp("test_service")
    push_testing_objstore(bucket)
    push_is_running_service()

    try:
        service = Service.create(service_type="identity",
                                 service_url="identity")

        assert(service.uid() is not None)
        assert(service.uid().startswith("STAGE1"))

        service.create_stage2(service_uid="Z9-Z8", response=service.uid())

        assert(service.is_identity_service())
        assert(not service.should_refresh_keys())
        assert(service.is_unlocked())
        assert(not service.is_locked())

        passphrase = PrivateKey.random_passphrase()

        data = service.to_data(passphrase)

        service2 = IdentityService.from_data(data, passphrase)

        assert(service2.uid() == service.uid())
        assert(service2.is_unlocked())
        assert(not service2.is_locked())
        assert(service2.is_identity_service())
        assert(service.canonical_url() == service2.canonical_url())
        assert(not service2.should_refresh_keys())

        keys = service.dump_keys()

        keys = service.load_keys(keys)

        assert(keys[service.private_key().fingerprint()] ==
               service.private_key())
        assert(keys[service.private_certificate().fingerprint()] ==
               service.private_certificate())

        service.refresh_keys()

        assert(service.last_key_update() > service2.last_key_update())
        assert(service.last_certificate().public_key() ==
               service2.public_certificate())
        assert(service.last_key() == service2.private_key())
    except:
        pop_is_running_service()
        pop_testing_objstore()
        raise

    pop_is_running_service()
    pop_testing_objstore()
Beispiel #22
0
    def _get_service_info(self, identity_service):
        """Return the service info for the passed identity service"""
        try:
            return self._service_info[identity_service]
        except:
            pass

        # can we read this from a file?
        service_file = "%s/service_%s" % (Wallet._wallet_dir(
        ), _base64.b64encode(identity_service.encode("utf-8")).decode("utf-8"))

        try:
            with open(service_file, "rb") as FILE:
                service_info = _Service.from_data(
                    _unpack_arguments(FILE.read()))
                self._service_info[identity_service] = service_info
                return service_info
        except:
            pass

        try:
            key = _PrivateKey()
            response = _call_function(identity_service, response_key=key)
            service = _Service.from_data(response["service_info"])
        except Exception as e:
            raise LoginError(
                "Error connecting to the login service %s: Error = %s" %
                (identity_service, str(e)))

        if not service.is_identity_service():
            raise LoginError("You cannot log into something that is not "
                             "a valid identity service!")

        self._service_info[identity_service] = service

        # save this for future reference
        with open(service_file, "wb") as FILE:
            FILE.write(_pack_arguments(service.to_data()))

        return service
Beispiel #23
0
    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
Beispiel #24
0
def get_trusted_services():
    """Return a dictionary of all trusted services indexed by
       their type
    """
    from Acquire.Service import is_running_service as _is_running_service

    if _is_running_service():
        from Acquire.Service import get_this_service as _get_this_service
        from Acquire.Service import Service as _Service

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

        # we already trust ourselves
        service = _get_this_service()

        trusted_services = {}
        trusted_services[service.service_type()] = [service]

        bucket = _get_service_account_bucket()

        uidkey = "_trusted/uid/"
        datas = _ObjectStore.get_all_objects(bucket, uidkey)

        for data in datas:
            remote_service = _Service.from_data(data)

            if remote_service.should_refresh_keys():
                # need to update the keys in our copy of the service
                remote_service.refresh_keys()
                key = "%s/%s" % (uidkey, remote_service.uid())
                _ObjectStore.set_object_from_json(bucket, key,
                                                  remote_service.to_data())

            if remote_service.service_type() in datas:
                datas[remote_service.service_type()].append(remote_service)
            else:
                datas[remote_service.service_type()] = [remote_service]

        return datas
    else:
        # this is running on the client
        from Acquire.Client import Wallet as _Wallet
        wallet = _Wallet()
        return wallet.get_services()
Beispiel #25
0
def refresh_service_keys_and_certs(service, force_refresh=False):
    """This function will check if any key rotation is needed, and
       if so, it will automatically refresh the keys and certificates.
       The old keys and certificates will be stored in a database of
       old keys and certificates
    """
    assert_running_service()

    if service._uid == "STAGE1":
        return service

    if (not force_refresh) and (not service.should_refresh_keys()):
        return service

    # ensure that the current keys are saved to the object store
    save_service_keys_to_objstore()

    # generate new keys
    last_update = service.last_key_update()
    service.refresh_keys()

    # now lock the object store so that we are the only function
    # that can write the new keys to global state
    from Acquire.Service import get_service_account_bucket as \
        _get_service_account_bucket
    from Acquire.Service import Service as _Service
    from Acquire.ObjectStore import Mutex as _Mutex
    from Acquire.ObjectStore import ObjectStore as _ObjectStore

    bucket = _get_service_account_bucket()
    m = _Mutex(key=service.uid(), bucket=bucket)

    service_data = _ObjectStore.get_object_from_json(bucket, _service_key)
    service_info = _Service.from_data(service_data)

    if service_info.last_key_update() == last_update:
        # no-one else has beaten us - write the updated keys to global state
        _ObjectStore.set_object_from_json(
            bucket, _service_key, service.to_data(_get_service_password()))

    m.unlock()

    # clear the cache as we will need to load a new object
    clear_serviceinfo_cache()

    return get_this_service(need_private_access=True)
Beispiel #26
0
    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
Beispiel #27
0
    def get_service(self, service_url=None, service_uid=None):
        """Ask the registry to return the service with specified
           service_url or service_uid
        """
        if service_url is None and service_uid is None:
            raise PermissionError(
                "You must specify one of service_url or service_uid")

        args = {"service_uid": service_uid,
                "service_url": service_url}

        response = self.call_function(function="get_service",
                                      args=args)

        from Acquire.Service import Service as _Service
        service = _Service.from_data(response["service_info"])

        return service
Beispiel #28
0
    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__)
Beispiel #29
0
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 test_service(service_url, aaai_services):
    # get the public service from the default API frontend
    privkey = get_private_key("testing")
    response = call_function(service_url, response_key=privkey)
    service = Service.from_data(response["service_info"])

    # also read the service from the object store directly
    push_testing_objstore(aaai_services["_services"][service_url])
    push_is_running_service()
    private_service = get_this_service(need_private_access=True)
    pop_is_running_service()
    pop_testing_objstore()

    # create some test data that contain unicode characters for
    # testing encryption, signing and both encryption and signing
    data = {"hello": "'å∫ç∂ƒ©˙˚'", "key": privkey.public_key().to_data()}

    encrypted = service.encrypt_data(data)
    decrypted = private_service.decrypt_data(encrypted)

    assert(data == decrypted)

    signed = private_service.sign_data(data)
    verified = service.verify_data(signed)

    assert(data == verified)

    enc_sign = service.encrypt_data(private_service.sign_data(data))
    dec_ver = service.verify_data(private_service.decrypt_data(enc_sign))

    assert(data == dec_ver)

    service.call_function("admin/test")

    admin_user = aaai_services[service_url]["user"]
    auth = Authorisation(user=admin_user,
                         resource="dump_keys %s" % service.uid())

    service.call_function(
        function="dump_keys", args={"authorisation": auth.to_data()})