Beispiel #1
0
    def __build_permissions(self):
        granted = []
        revoked = []
        granted_field_lookup = {}
        pbdb = PermissionBatchDatabase(default_pb_db())
        permissions = UnifPermissions(get_ipfs_client(), self.__my_uapp_sc,
                                      pbdb)
        permissions.load_consumer_perms(self.__requesting_app)

        permission_obj = permissions.get_all_perms()
        # schema_id = self.__my_db_schemas[0]['pkey']  # tmp - only 1 db schema

        for user, perms in permission_obj['permissions'].items():
            log.debug(perms)
            schema_perms = perms['0']  # tmp - only 1 db schema
            if schema_perms['perms'] == '':
                revoked.append(eosio_account.string_to_name(user))
            else:
                granted.append(eosio_account.string_to_name(user))
                native_id = self.__my_lookup.get_native_user_id(user)
                granted_field_lookup[native_id] = schema_perms['perms'].split(
                    ',')
                # required
                granted_field_lookup[native_id].append('account_name')

        return granted, revoked, granted_field_lookup
def get_proof():
    conf = app.unification_config
    d = flask.request.get_json()
    user = d['user']
    consumer = d['consumer']
    ipfs_hash = d['ipfs_hash']
    schema_id = d['schema_id']

    provider_uapp = UnificationUapp(get_eos_rpc_client(),
                                    conf['uapp_contract'])

    permission_db = PermissionBatchDatabase(pb_default_db())

    permissions = UnifPermissions(get_ipfs_client(), provider_uapp,
                                  permission_db)

    if ipfs_hash is not None:
        permissions.load_perms_from_ipfs(ipfs_hash)
    else:
        permissions.load_consumer_perms(consumer)

    proof = permissions.get_proof(user, schema_id=schema_id)

    # ToDo: send as JWT
    return_d = {'proof': proof}

    return flask.jsonify(return_d), 200
def systest_merkle_proof_permissions():
    ipfs = get_ipfs_client()
    users, consumers, providers = compile_actors()

    for provider in providers:
        log.debug(f'run systest_merkle_proof_'
                  f'permissions for Provider {provider}')

        provider_uapp = UnificationUapp(get_eos_rpc_client(), provider)

        permission_db = PermissionBatchDatabase(pb_default_db())
        permissions = UnifPermissions(ipfs, provider_uapp, permission_db)

        for consumer in consumers:
            if consumer != provider:
                log.debug(f'Provider {provider}: load '
                          f'permissions for Consumer {consumer}')
                permissions.load_consumer_perms(consumer)

                permissions_obj = permissions.get_all_perms()

                tree = MerkleTree()

                for user, perm in permissions_obj['permissions'].items():
                    for schema_id, schema_perm in perm.items():
                        tree.add_leaf(json.dumps(schema_perm))

                tree.grow_tree()

                log.debug(f"Generated merkle root: {tree.get_root_str()}")
                log.debug(f"Recorded merkle root: "
                          f"{permissions_obj['merkle_root']}")

                for user, perm in permissions_obj['permissions'].items():
                    for schema_id, schema_perm in perm.items():
                        requested_leaf = json.dumps(schema_perm)
                        proof_chain = tree.get_proof(requested_leaf,
                                                     is_hashed=False)
                        log.debug(f'Permission leaf for {user}:'
                                  f' {requested_leaf}')
                        log.debug(f'Proof chain for {user} - '
                                  f'Schema {schema_id} '
                                  f'permission leaf: '
                                  f'{json.dumps(proof_chain)}')

                        # simulate only having access to leaf,
                        # root and proof chain for leaf
                        verify_tree = MerkleTree()

                        is_good = verify_tree.verify_leaf(
                            requested_leaf,
                            permissions_obj['merkle_root'],
                            proof_chain,
                            is_hashed=False)

                        log.debug(f'Leaf is valid: {is_good}')

                        assert is_good
def get_proof_tx():
    d = flask.request.get_json()
    user = d['user']
    proc_id = d['proc_id']

    permission_db = PermissionBatchDatabase(pb_default_db())

    operation_data = permission_db.get_op_for_user(user, proc_id)

    return_data = {'processed': False, 'proof_tx': None, 'found': False}

    if operation_data:
        return_data['found'] = True
        if operation_data['proof_tx']:
            return_data['processed'] = True
            return_data['proof_tx'] = operation_data['proof_tx']

    return flask.jsonify(return_data), 200
def systest_check_permission_requests():

    ipfs = get_ipfs_client()
    users, consumers, providers = compile_actors()

    for provider in providers:
        log.debug(f'run systest_check_permission_requests'
                  f' for Provider {provider}')

        provider_uapp = UnificationUapp(get_eos_rpc_client(), provider)

        permission_db = PermissionBatchDatabase(pb_default_db())
        permissions = UnifPermissions(ipfs, provider_uapp, permission_db)

        for consumer in consumers:
            if consumer != provider:
                log.debug(f'Provider {provider}: load permissions '
                          f'for Consumer {consumer}')
                permissions.load_consumer_perms(consumer)
                for user in users:
                    user_permissions = permissions.get_user_perms_for_all_schemas(
                        user)
                    for schema_id, user_perms in user_permissions.items():
                        log.debug(f'User {user}, '
                                  f'Schema {schema_id}: {user_perms}')
                        is_valid = permissions.verify_permission(user_perms)
                        log.debug(f'Perm sig valid: {is_valid}')

                        assert is_valid

                        demo_conf_check = demo_config['demo_permissions'][
                            user][consumer][provider]

                        demo_conf_fields = demo_conf_check['fields']
                        demo_conf_granted = demo_conf_check['granted']
                        demo_conf_schema_id = demo_conf_check['schema_id']

                        assert int(demo_conf_schema_id) == int(schema_id)

                        if demo_conf_granted:
                            log.debug("Permission granted")
                            log.debug(f"Demo fields: {demo_conf_fields}, "
                                      f"recorded fields: "
                                      f"{user_perms['perms']}")
                            assert demo_conf_fields == user_perms['perms']
                        else:
                            log.debug("Permission not granted. Recorded "
                                      "perms should be empty")
                            log.debug(f"Recorded fields: "
                                      f"{user_perms['perms']}")
                            assert user_perms['perms'] == ''
Beispiel #6
0
    def check_and_process_stashed(self, consumer_account):
        from haiku_node.permissions.perm_batch_db import (
            PermissionBatchDatabase, default_db as pb_db)

        pb = PermissionBatchDatabase(pb_db())

        latest_stash = pb.get_stash(consumer_account)
        if latest_stash is not None:
            tx_id = self.__uapp.update_userperms(consumer_account,
                                                 latest_stash['ipfs_hash'],
                                                 latest_stash['merkle_root'])
            pb.update_batch_stashes_with_tx(latest_stash['stash_id'], tx_id)
            pb.delete_stash(latest_stash['stash_id'])
def data_request():
    try:
        d = flask.request.get_json()

        # Validate requesting app against smart contracts
        # config is this Haiku Node's config fle, containing its UApp
        # Smart Contract account/address and the EOS RPC server/port used for
        # communicating with the blockchain.
        conf = app.unification_config

        sender = d['eos_account_name']
        recipient = conf['uapp_contract']

        if sender == recipient:
            return error_request_self()

        bundle_d = unbundle(app.keystore, sender, d)

        eos_client = get_eos_rpc_client()

        # Init the validation class for THIS Haiku, and validate the
        # REQUESTING APP.
        v = UnificationAppScValidation(eos_client, d['eos_account_name'])

        # If the REQUESTING APP is valid according to MOTHER, then we can
        # generate the data. If not, return an invalid_app response
        if v.valid():
            users = bundle_d.get('users')
            request_id = bundle_d.get('request_id')

            # before processing data, check for any stashed permissions
            ipfs = get_ipfs_client()
            provider_uapp = UnificationUapp(eos_client, conf['uapp_contract'])

            permission_db = PermissionBatchDatabase(pb_default_db())
            permissions = UnifPermissions(ipfs, provider_uapp, permission_db)
            permissions.check_and_process_stashed(sender)

            return obtain_data(app.keystore, sender, eos_client,
                               conf['uapp_contract'], users, request_id)
        else:
            return invalid_app()

    except InvalidSignature:
        return invalid_response()

    except Exception as e:
        logger.exception(e)
        return generic_error()
 def __init__(self, permissions_db: Path):
     self.db = PermissionBatchDatabase(permissions_db)
     self.ipfs = get_ipfs_client()
class PermissionBatcher:
    def __init__(self, permissions_db: Path):
        self.db = PermissionBatchDatabase(permissions_db)
        self.ipfs = get_ipfs_client()

    def add_to_queue(self, *kwargs):
        return self.db.add(*kwargs)

    def process_batch_queue(self, num=10):

        provider_uapp = get_self_uapp()
        permissions = UnifPermissions(self.ipfs, provider_uapp, self.db)

        processed = []

        for item in self.db.get_unprocessed(num):
            perm = {
                'perms': item['perms'],
                'p_nonce': item['p_nonce'],
                'p_sig': item['p_sig'],
                'pub_key': item['pub_key'],
                'schema_id': item['schema_id'],
                'consumer': item['consumer_account'],
                'user': item['end_user_account']
            }
            is_added = permissions.add_change_request(item['consumer_account'],
                                                      item['end_user_account'],
                                                      perm)

            b_proc = {
                'op_id': item['op_id'],
                'consumer': item['consumer_account'],
                'is_added': is_added
            }

            processed.append(b_proc)

        ret_data = permissions.process_change_requests()

        for item in processed:
            if item['is_added']:
                ret_d = ret_data[item['consumer']]
                if ret_d['bc']:
                    self.db.update_processed(item['op_id'],
                                             proof_tx=ret_d['proof_tx'])

                else:
                    stash_id = self.db.stash_permission(
                        ret_d['stash']['consumer'],
                        ret_d['stash']['ipfs_hash'],
                        ret_d['stash']['merkle_root'])

                    self.db.update_processed(item['op_id'], stash_id=stash_id)
            else:
                # Currently fails if sig is invalid, so delete
                self.db.delete_op(item['op_id'])

        # cleanup stashes
        for c, ret_d in ret_data.items():
            if ret_d['stash_id_committed'] is not None:
                self.db.update_batch_stashes_with_tx(
                    ret_d['stash_id_committed'], ret_d['proof_tx'])
                self.db.delete_stash(ret_d['stash_id_committed'])

        log.debug(ret_data)

        return ret_data