Ejemplo n.º 1
0
def explain_impl(record, debug):
    """
    Explains which ACLs will be applied to a record and what the added ACL property will look like.

    :param record a path to a file containing record metadata or '-' to read the metadata from stdin.
    """
    class Model:
        def __init__(self):
            self.id = 'record-id'

    with open(record, 'r') if record is not "-" else sys.stdin as f:
        record_metadata = json.load(f)
        if '$schema' not in record_metadata:
            print('Please add $schema to record metadata')
            return
        invenio_record = Record(record_metadata)
        invenio_record.model = Model()

        schema = record_metadata['$schema']
        if schema.startswith('http://') or schema.startswith('https://'):
            schema = current_jsonschemas.url_to_path(schema)

        print('Possible ACLs')
        for acl in ACL.query.all():
            if schema in acl.schemas:
                print('    ', type(acl).__name__, acl)

                for k in dir(acl):
                    if k.startswith('_'): continue
                    if k in ('metadata', 'query'): continue
                    val = getattr(acl, k)
                    if not callable(val) and val:
                        if isinstance(val, list):
                            print('        %s = %s' %
                                  (k, [str(x) for x in val]))
                        else:
                            print('        %s = %s' % (k, val))
        print()

        applicable_acls = []
        for acl in current_explicit_acls.acl_models:
            print('Checking ACLs of type', acl)
            if debug and hasattr(acl, '_get_percolate_query'):
                index, _doc_type = current_record_to_index(invenio_record)
                index = acl.get_acl_index_name(index)
                doc_type = current_app.config[
                    'INVENIO_EXPLICIT_ACLS_DOCTYPE_NAME']
                print(
                    '   Will run percolate query on index %s and doc_type %s:'
                    % (index, doc_type))
                print('\n'.join('        ' + x
                                for x in json.dumps(acl._get_percolate_query(
                                    invenio_record),
                                                    indent=4).split('\n')))
            found_acls = list(acl.get_record_acls(invenio_record))
            for acl in found_acls:
                print('    found match: %s with priority of %s' %
                      (acl, acl.priority))
                for actor in acl.actors:
                    print('        ', actor)
            applicable_acls.extend(found_acls)
        print()

        if not applicable_acls:
            print('The record is not matched by any ACLs')
            return

        matching_acls = list(
            current_explicit_acls.get_record_acls(invenio_record))

        print(
            'Of these, the following ACLs will be used (have the highest priority):'
        )
        for acl in matching_acls:
            print('    ', acl)
            for actor in acl.actors:
                print('        ', actor)

        print()

        print('The ACLs will get serialized to the following element')
        print(
            json.dumps(
                {
                    '_invenio_explicit_acls':
                    current_explicit_acls.serialize_record_acls(matching_acls)
                },
                indent=4))