def get_record_permissions(recid=None):
    if not recid:
        return False

    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    permissions = dict()
    permissions['u_edit'] = ActionUsers.query_by_action(
        action_edit_record).all()
    permissions['u_read'] = ActionUsers.query_by_action(
        action_read_record).all()
    permissions['u_index'] = ActionUsers.query_by_action(
        action_index_record).all()

    permissions['r_edit'] = ActionRoles.query_by_action(
        action_edit_record).all()
    permissions['r_read'] = ActionRoles.query_by_action(
        action_read_record).all()
    permissions['r_index'] = ActionRoles.query_by_action(
        action_index_record).all()

    result = permissions['u_edit'] + permissions['u_read'] + permissions['u_index'] + \
        permissions['r_edit'] + permissions['r_read'] + permissions['r_index']

    return result
Beispiel #2
0
def get_record_permissions(recid=None):
    if not recid:
        return False

    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    permissions = dict()
    permissions['u_edit'] = ActionUsers.query_by_action(
        action_edit_record).all()
    permissions['u_read'] = ActionUsers.query_by_action(
        action_read_record).all()
    permissions['u_index'] = ActionUsers.query_by_action(
        action_index_record).all()

    permissions['r_edit'] = ActionRoles.query_by_action(
        action_edit_record).all()
    permissions['r_read'] = ActionRoles.query_by_action(
        action_read_record).all()
    permissions['r_index'] = ActionRoles.query_by_action(
        action_index_record).all()

    result = permissions['u_edit'] + permissions['u_read'] + permissions['u_index'] + \
        permissions['r_edit'] + permissions['r_read'] + permissions['r_index']

    return result
def test_invenio_access_permission_cache_redis(app):
    """Caching the user using redis."""
    cache = RedisCache()
    InvenioAccess(app, cache=cache)
    with app.test_request_context():
        user_can_all = User(email='*****@*****.**')
        user_can_open = User(email='*****@*****.**')

        db.session.add(user_can_all)
        db.session.add(user_can_open)

        db.session.add(ActionUsers(action='open', user=user_can_all))

        db.session.flush()

        identity_open = FakeIdentity(UserNeed(user_can_open.id))

        permission_open = DynamicPermission(ActionNeed('open'))
        assert not permission_open.allows(identity_open)
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1)]), set([]))

        db.session.add(ActionUsers(action='open', user=user_can_open))
        db.session.flush()

        permission_open = DynamicPermission(ActionNeed('open'))
        assert permission_open.allows(identity_open)
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1),
             Need(method='id', value=2)]), set([]))
def oauth2(app, db):
    """Creates authentication tokens for test.

    Add these attributes in the app object and return app:
    - user: a fake user that have authorization to archive_read and write
    - token: api token for user
    """
    from invenio_access.models import ActionUsers
    from invenio_oauth2server.models import Token

    from invenio_archivematica.permissions import archive_read, archive_write

    datastore = app.extensions['security'].datastore
    app.user = datastore.create_user(email='*****@*****.**',
                                     password='******',
                                     active=True)
    db.session.commit()
    db.session.add(ActionUsers.allow(archive_read, user=app.user))
    db.session.add(ActionUsers.allow(archive_write, user=app.user))
    app.token = Token.create_personal('test-',
                                      app.user.id,
                                      scopes=['archive:actions'],
                                      is_internal=True).access_token
    db.session.commit()

    return app
def users(app):
    # Create test users
    encrypted_password = encrypt_password('123456')
    user = User(
        email='*****@*****.**',
        password=encrypted_password,
        active=True
    )
    user_partially_allowed = User(
        email='*****@*****.**',
        password=encrypted_password,
        active=True,
    )
    user_allowed = User(
        email='*****@*****.**',
        password=encrypted_password,
        active=True,
    )

    db.session.add_all(
        [user, user_partially_allowed, user_allowed]
    )
    db.session.commit()

    # Create actions for the allowed user
    restricted_collection_action = ActionUsers(
        action='view-restricted-collection',
        argument='Restricted Collection',
        user_id=user_allowed.id
    )
    another_restricted_collection_action = ActionUsers(
        action='view-restricted-collection',
        argument='Another Restricted Collection',
        user_id=user_allowed.id
    )

    # Create actions for the partially allowed user
    partial_restricted_collection_action = ActionUsers(
        action='view-restricted-collection',
        argument='Restricted Collection',
        user_id=user_partially_allowed.id
    )

    db.session.add_all(
        [
            restricted_collection_action,
            another_restricted_collection_action,
            partial_restricted_collection_action
        ]
    )
    db.session.commit()

    yield

    SessionActivity.query.delete()
    ActionUsers.query.filter_by(action='view-restricted-collection').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    db.session.commit()
Beispiel #6
0
def test_permission_factory(app, db, action, permission_factory):
    """Test revisions."""
    InvenioAccess(app)

    rec_uuid = uuid.uuid4()

    with db.session.begin_nested():
        user_all = User(email='*****@*****.**')
        user_one = User(email='*****@*****.**')
        user_none = User(email='*****@*****.**')
        db.session.add(user_all)
        db.session.add(user_one)
        db.session.add(user_none)

        db.session.add(ActionUsers(action=action, user=user_all,
                                   argument=None))
        db.session.add(
            ActionUsers(action=action, user=user_one, argument=str(rec_uuid)))

        record = Record.create({'title': 'permission test'}, id_=rec_uuid)

    # Create a record and assign permissions.
    permission = permission_factory(record)

    # Assert which permissions has access.
    assert permission.allows(FakeIdentity(UserNeed(user_all.id)))
    assert permission.allows(FakeIdentity(UserNeed(user_one.id)))
    assert not permission.allows(FakeIdentity(UserNeed(user_none.id)))
Beispiel #7
0
def test_dynamic_permission_needs_cache_invalidation(app):
    """Testing DynamicPermission refreshes needs.

    This is important when protecting a view with
    @permission.require(http_exception=403)
    If cache does not get invalidated, the needs will only be refreshed when
    the Python process restarts.
    """
    cache = SimpleCache()
    InvenioAccess(app, cache=cache)
    with app.test_request_context():
        user_can_all = User(email='*****@*****.**')
        user_can_open = User(email='*****@*****.**')
        db.session.add(user_can_all)
        db.session.add(user_can_open)

        db.session.add(ActionUsers(action='open', user=user_can_all))
        db.session.flush()

        permission_open = DynamicPermission(ActionNeed('open'))

        assert permission_open.needs == set([Need(method='id', value=1)])

        db.session.add(ActionUsers(action='open', user=user_can_open))
        db.session.flush()

        assert permission_open.needs == set(
            [Need(method='id', value=1), Need(method='id', value=2)]
            )
Beispiel #8
0
    def _add_experiment_permissions(cls, data, id_):
        """Add read permissions to everybody assigned to experiment."""
        exp_need = exp_need_factory(data['_experiment'])

        # give read access to members of collaboration
        for au in ActionUsers.query_by_action(exp_need).all():
            try:
                ActionUsers.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']).filter_by(
                        user=au.user).one()
            except NoResultFound:
                db.session.add(
                    ActionUsers.allow(RECORD_ACTION_NEEDS(id_)['record-read'],
                                      user=au.user))
                data['_access']['record-read']['users'].append(au.user.id)

        for ar in ActionRoles.query_by_action(exp_need).all():
            try:
                ActionRoles.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']).filter_by(
                        role=ar.role).one()
            except NoResultFound:
                db.session.add(
                    ActionRoles.allow(RECORD_ACTION_NEEDS(id_)['record-read'],
                                      role=ar.role))
                data['_access']['record-read']['roles'].append(ar.role.id)
Beispiel #9
0
def test_invenio_access_permission_for_users(app):
    """User can access to an action allowed/denied to the user"""
    InvenioAccess(app)
    with app.test_request_context():
        db.session.begin(nested=True)
        user_can_all = User(email='*****@*****.**')
        user_can_read = User(email='*****@*****.**')
        user_can_open = User(email='*****@*****.**')

        db.session.add(user_can_all)
        db.session.add(user_can_read)
        db.session.add(user_can_open)

        db.session.add(ActionUsers(action='open', user=user_can_all))
        db.session.add(ActionUsers(action='open', user=user_can_open))

        db.session.add(ActionUsers(action='read', user=user_can_all))
        db.session.add(ActionUsers(action='read', user=user_can_read))
        db.session.commit()

        permission_open = DynamicPermission(ActionNeed('open'))
        permission_read = DynamicPermission(ActionNeed('read'))

        identity_all = FakeIdentity(UserNeed(user_can_all.id))
        identity_read = FakeIdentity(UserNeed(user_can_read.id))
        identity_open = FakeIdentity(UserNeed(user_can_open.id))

        assert permission_open.allows(identity_all)
        assert permission_read.allows(identity_all)

        assert permission_open.allows(identity_open)
        assert not permission_read.allows(identity_open)

        assert not permission_open.allows(identity_read)
        assert permission_read.allows(identity_read)
    def _add_experiment_permissions(cls, data, id_):
        """Add read permissions to everybody assigned to experiment."""
        exp_need = exp_need_factory(data['_experiment'])

        # give read access to members of collaboration
        for au in ActionUsers.query_by_action(exp_need).all():
            try:
                ActionUsers.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']
                ).filter_by(user=au.user).one()
            except NoResultFound:
                db.session.add(
                    ActionUsers.allow(
                        RECORD_ACTION_NEEDS(id_)['record-read'],
                        user=au.user
                    )
                )
                data['_access']['record-read']['users'].append(au.user.id)

        for ar in ActionRoles.query_by_action(exp_need).all():
            try:
                ActionRoles.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']
                ).filter_by(role=ar.role).one()
            except NoResultFound:
                db.session.add(
                    ActionRoles.allow(
                        RECORD_ACTION_NEEDS(id_)['record-read'],
                        role=ar.role
                    )
                )
                data['_access']['record-read']['roles'].append(ar.role.id)
Beispiel #11
0
def test_invenio_access_permission_cache(app):
    """Caching the user using memory caching."""
    cache = SimpleCache()
    InvenioAccess(app, cache=cache)
    with app.test_request_context():
        user_can_all = User(email='*****@*****.**')
        user_can_open = User(email='*****@*****.**')
        user_can_open_1 = User(email='*****@*****.**')

        db.session.add(user_can_all)
        db.session.add(user_can_open)
        db.session.add(user_can_open_1)

        db.session.add(ActionUsers(action='open', user=user_can_all))

        db.session.flush()

        permission_open = DynamicPermission(ActionNeed('open'))

        identity_open = FakeIdentity(UserNeed(user_can_open.id))

        assert not permission_open.allows(identity_open)
        assert current_access.get_action_cache('open') == (
            set([Need(method='id', value=1)]),
            set([])
        )

        db.session.add(ActionUsers(action='open', user=user_can_open))
        db.session.flush()

        permission_open = DynamicPermission(ActionNeed('open'))
        assert permission_open.allows(identity_open)
        assert current_access.get_action_cache('open') == (
            set([Need(method='id', value=1),
                 Need(method='id', value=2)]),
            set([])
        )

        db.session.add(ActionUsers(action='open', argument=1,
                                   user=user_can_open_1))
        db.session.flush()

        identity_open_1 = FakeIdentity(UserNeed(user_can_open_1.id))
        permission_open_1 = DynamicPermission(
            ParameterizedActionNeed('open', '1'))
        assert not permission_open.allows(identity_open_1)
        assert permission_open_1.allows(identity_open_1)
        assert current_access.get_action_cache('open::1') == (
            set([Need(method='id', value=1),
                 Need(method='id', value=2),
                 Need(method='id', value=3)]),
            set([])
        )
        assert current_access.get_action_cache('open') == (
            set([Need(method='id', value=1),
                 Need(method='id', value=2)]),
            set([])
        )
Beispiel #12
0
def permissions(db, bucket):
    """Permission for users."""
    users = {
        None: None,
    }

    for user in [
            'auth', 'location', 'bucket',
            'objects', 'objects-read-version']:
        users[user] = create_test_user(
            email='{0}@invenio-software.org'.format(user),
            password='******',
            active=True
        )

    location_perms = [
        location_update_all,
        bucket_read_all,
        bucket_read_versions_all,
        bucket_update_all,
        bucket_listmultiparts_all,
        object_read_all,
        object_read_version_all,
        object_delete_all,
        object_delete_version_all,
        multipart_read_all,
        multipart_delete_all,
    ]

    bucket_perms = [
        bucket_read_all,
        object_read_all,
        bucket_update_all,
        object_delete_all,
        multipart_read_all,
    ]

    objects_perms = [
        object_read_all,
    ]

    for perm in location_perms:
        db.session.add(ActionUsers(
            action=perm.value,
            user=users['location']))
    for perm in bucket_perms:
        db.session.add(ActionUsers(
            action=perm.value,
            argument=str(bucket.id),
            user=users['bucket']))
    for perm in objects_perms:
        db.session.add(ActionUsers(
            action=perm.value,
            argument=str(bucket.id),
            user=users['objects']))
    db.session.commit()

    yield users
def create_record(collection):
    """Basic test view."""

    collection = Collection.query.filter(
        Collection.name == collection).first_or_404()

    schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'),
                     url_for('records.jsonschema',
                             collection=collection.name))

    data, pid, recid = construct_record(collection,
                                        json.loads(request.get_data()),
                                        current_user.id,
                                        schema)

    try:
        record = Record.create(data, id_=recid)
    except ValidationError as error:
        print("============================")
        print(error.message)
        print("============================")

        db.session.rollback()
        resp = jsonify(**{'message': error.message})
        resp.status_code = 400
        return resp

    # Invenio-Indexer is delegating the document inferring to
    # Invenio-Search which is analysing the string splitting by `/` and
    # using `.json` to be sure that it cans understand the mapping.
    record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

    indexer = RecordIndexer()
    indexer.index(record)

    # Creating permission needs for the record
    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    # Giving index, read, write permissions to user/creator
    db.session.add(ActionUsers.allow(action_edit_record, user=current_user))
    db.session.add(ActionUsers.allow(action_read_record, user=current_user))
    db.session.add(ActionUsers.allow(action_index_record, user=current_user))

    db.session.commit()

    resp = jsonify(**{'pid': pid})
    resp.status_code = 200
    return resp
def create_record(collection):
    """Basic test view."""

    collection = Collection.query.filter(
        Collection.name == collection).first_or_404()

    schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'),
                     url_for('records.jsonschema',
                             collection=collection.name))

    data, pid, recid = construct_record(collection,
                                        json.loads(request.get_data()),
                                        current_user.id,
                                        schema)

    try:
        record = Record.create(data, id_=recid)
    except ValidationError as error:
        print("============================")
        print(error.message)
        print("============================")

        db.session.rollback()
        resp = jsonify(**{'message': error.message})
        resp.status_code = 400
        return resp

    # Invenio-Indexer is delegating the document inferring to
    # Invenio-Search which is analysing the string splitting by `/` and
    # using `.json` to be sure that it cans understand the mapping.
    record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

    indexer = RecordIndexer()
    indexer.index(record)

    # Creating permission needs for the record
    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    # Giving index, read, write permissions to user/creator
    db.session.add(ActionUsers.allow(action_edit_record, user=current_user))
    db.session.add(ActionUsers.allow(action_read_record, user=current_user))
    db.session.add(ActionUsers.allow(action_index_record, user=current_user))

    db.session.commit()

    resp = jsonify(**{'pid': pid})
    resp.status_code = 200
    return resp
def users(app, db):
    """Create users."""
    def dump_user(user):
        """User object to dict."""
        return {
            'email': user.email,
            'id': user.id,
            'password': password
        }
    password = '******'
    with db.session.begin_nested():
        datastore = app.extensions['security'].datastore
        # create users
        hashed_password = hash_password(password)
        user1 = datastore.create_user(email='*****@*****.**',
                                      password=hashed_password, active=True)
        user2 = datastore.create_user(email='*****@*****.**',
                                      password=hashed_password, active=True)
        # Give role to admin
        db.session.add(ActionUsers(action='admin-access',
                                   user=user1))
    db.session.commit()
    return {
        'user1': dump_user(user1),
        'user2': dump_user(user2)
    }
    def _add_deposit_permissions(cls, data, id_):
        """Inherit permissions after deposit."""
        data['_access'] = {
            DEPOSIT_TO_RECORD_ACTION_MAP[action]: permission
            for action, permission in data['_access'].items()
        }

        for action, permission in data['_access'].items():
            for role in permission['roles']:
                role = Role.query.filter_by(id=role).one()
                try:
                    ActionRoles.query.filter_by(action=action,
                                                argument=str(id_),
                                                role_id=role.id).one()
                except NoResultFound:
                    db.session.add(
                        ActionRoles.allow(RECORD_ACTION_NEEDS(id_)[action],
                                          role=role))
            for user in permission['users']:
                user = User.query.filter_by(id=user).one()
                try:
                    ActionUsers.query.filter_by(action=action,
                                                argument=str(id_),
                                                user_id=user.id).one()
                except NoResultFound:
                    db.session.add(
                        ActionUsers.allow(RECORD_ACTION_NEEDS(id_)[action],
                                          user=user))
Beispiel #17
0
def test_file_permissions(app, db, record_with_files_creation, user,
                          access_right, expected):
    """Test file permissions."""
    pid, record, record_url = record_with_files_creation

    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(ActionUsers.allow(ActionNeed('admin-access'), user=admin))
    db.session.commit()

    # Create test record
    record['access_right'] = access_right
    record['owners'] = [owner.id]
    record.commit()
    db.session.commit()

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value=pid.pid_value,
        filename='Test.pdf',
    )
    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
def users(app):
    """Create user fixtures."""
    hashed_password = hash_password('123456')
    user = User(email='*****@*****.**',
                password=hashed_password,
                active=True)
    user_allowed = User(email='*****@*****.**',
                        password=hashed_password,
                        active=True)

    db.session.add_all([user, user_allowed])
    db.session.commit()

    author_admin = ActionUsers(action='admin-holdingpen-authors',
                               user_id=user_allowed.id)

    db.session.add(author_admin)
    db.session.commit()

    yield

    ActionUsers.query.filter_by(action='admin-holdingpen-authors').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    db.session.commit()
Beispiel #19
0
    def grant_vocabulary_editor_permission(cls, user_id,
                                           vocabulary_id) -> Dict[str, bool]:
        done = False
        msg = ''
        try:
            vocabulary = Vocabulary.query.filter_by(
                identifier=vocabulary_id).first()
            user = User.query.filter_by(id=user_id).first()
            if not vocabulary:
                msg = 'Vocabulary not found'
            elif not user:
                msg = 'User not found'
            else:
                db.session.add(
                    ActionUsers.allow(ObjectVocabularyEditor(vocabulary.id),
                                      user=user))
                db.session.commit()
                msg = 'Vocabulary Editor Permission granted over {0}'.format(
                    vocabulary.name)
                done = True

        except Exception as e:
            msg = str(e)
            # print(str(e))

        return msg, done
def users(app, db):
    """Create users."""
    users = {
        'cms_user': create_user_with_role('*****@*****.**',
                                          '*****@*****.**'),
        'cms_user2': create_user_with_role('*****@*****.**',
                                           '*****@*****.**'),
        'alice_user': create_user_with_role('*****@*****.**',
                                            '*****@*****.**'),
        'alice_user2': create_user_with_role('*****@*****.**',
                                             '*****@*****.**'),
        'atlas_user': create_user_with_role('*****@*****.**',
                                            '*****@*****.**'),
        'atlas_user2': create_user_with_role('*****@*****.**',
                                             '*****@*****.**'),
        'lhcb_user': create_user_with_role('*****@*****.**',
                                           '*****@*****.**'),
        'lhcb_user2': create_user_with_role('*****@*****.**',
                                            '*****@*****.**'),
        'superuser': create_user_with_role('*****@*****.**',
                                           '*****@*****.**'),
    }
    db.session.add(ActionUsers.allow(superuser_access, user=users['superuser']))
    db.session.commit()

    return users
Beispiel #21
0
def team_management(community):
    """Team management for communities.

    :param community_id: ID of the community to manage.
    """
    Action = namedtuple("Action", ["title", "name", "existing"])

    actions = []
    permissions = _get_permissions()
    for action in permissions:
        # 12 = len("communities-")
        a = Action(action[12:].replace("-", " ").capitalize(),
                     action,
                     ActionUsers.query_by_action(
                        _get_needs(action, community.id)).all())
        actions.append(a)
    ctx = mycommunities_ctx()
    ctx.update({
        "community": community,
        "actions": actions
    })
    return render_template(
        current_app.config['COMMUNITIES_TEAM_TEMPLATE'],
        **ctx
    )
Beispiel #22
0
def users():
    """Create users needed in this test module."""
    curator = User(
        email='*****@*****.**',
        password=hash_password('curator'),
        active=True,
    )
    scientist = User(
        email='*****@*****.**',
        password=hash_password('scientist'),
        active=True,
    )
    db.session.add_all([curator, scientist])
    db.session.commit()

    curator_action = ActionUsers(
        action='editor_manage_tickets',
        argument=None,
        user_id=curator.id,
    )
    db.session.add(curator_action)
    db.session.commit()

    yield

    ActionUsers.query.filter_by(action='editor_manage_tickets').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    User.query.filter_by(email='*****@*****.**').delete()
    db.session.commit()
    def give_admin_access_for_user(self, user):
        """Give admin access for users."""
        assert self.id

        db.session.add(ActionUsers.allow(SchemaAdminAction(self.id),
                                         user=user))
        db.session.flush()
Beispiel #24
0
    def create_user(self, email, entry):
        """Load a single user."""
        # when the user's password is set in the configuration, then
        # this overrides everything else
        password = current_app.config.get("RDM_RECORDS_USER_FIXTURE_PASSWORDS",
                                          {}).get(email)

        if not password:
            # for auto-generated passwords use letters, digits,
            # and some punctuation marks
            alphabet = string.ascii_letters + string.digits + "+,-_."
            gen_passwd = "".join(secrets.choice(alphabet) for i in range(20))
            password = entry.get("password") or gen_passwd

        user_data = {
            "email": email,
            "active": entry.get("active", False),
            "password": hash_password(password),
        }
        user = current_datastore.create_user(**user_data)

        for role in entry.get("roles", []):
            current_datastore.add_role_to_user(user, role)

        for action in entry.get("allow", []):
            action = current_access.actions[action]
            db.session.add(ActionUsers.allow(action, user_id=user.id))

        db.session.commit()
Beispiel #25
0
    def _make_user(role_name,
                   organisation='org',
                   organisation_is_shared=True,
                   access=None):
        name = role_name

        if organisation:
            make_organisation(organisation, is_shared=organisation_is_shared)
            name = organisation + name

        email = '{name}@rero.ch'.format(name=name)

        datastore = app.extensions['security'].datastore

        user = datastore.find_user(email=email)

        if user:
            record = UserRecord.get_user_by_email(email)
            return record

        user = datastore.create_user(email=email,
                                     password=hash_password('123456'),
                                     active=True)
        datastore.commit()

        role = datastore.find_role(role_name)
        if not role:
            role = Role(name=role_name)

        role.users.append(user)

        db.session.add(role)

        if access:
            db.session.add(ActionUsers.allow(ActionNeed(access), user=user))

        db.session.commit()

        data = {
            'pid': name,
            'email': email,
            'first_name': name[0].upper() + name[1:],
            'last_name': 'Doe',
            'role': role_name
        }

        if organisation:
            data['organisation'] = {
                '$ref':
                'https://sonar.ch/api/organisations/{organisation}'.format(
                    organisation=organisation)
            }

        record = UserRecord.create(data, dbcommit=True)
        record.reindex()
        db.session.commit()

        return record
Beispiel #26
0
 def delete_permission(self, allow, community_id=None):
     with db.session.begin_nested():
         user = accounts.datastore.get_user(self.user_id)
         # only add the access rights if the access control is enabled
         db.session.add(
             ActionUsers(action=communities_delete_all.value,
                         argument=str(community_id),
                         user=user,
                         exclude=not allow))
Beispiel #27
0
def create_user_with_access(session, username, action):
    user = _datastore.find_user(email=username)

    if not user:
        user = create_test_user(email=username, password='******')

    session.add(ActionUsers.allow(ActionNeed(action), user=user))

    return user
Beispiel #28
0
def admin_user(users, roles):
    """Give admin rights to a user."""
    user = users["user1"]
    role = roles["admin"]
    current_datastore.add_role_to_user(user, role)
    action = current_access.actions["superuser-access"]
    db.session.add(ActionUsers.allow(action, user_id=user.id))

    return user
    def _add_experiment_permissions(self, experiment, permissions):
        """Add read permissions to everybody assigned to experiment."""
        exp_need = exp_need_factory(experiment)

        # give read access to members of collaboration
        with db.session.begin_nested():
            for au in ActionUsers.query_by_action(exp_need).all():
                self._add_user_permissions(au.user, permissions, db.session)
            for ar in ActionRoles.query_by_action(exp_need).all():
                self._add_egroup_permissions(ar.role, permissions, db.session)
def add_record(metadata, collection, schema, force):
    """Add record."""

    collection = Collection.query.filter(
        Collection.name == collection).first()

    if collection is None:
        return

    data, pid, recid = construct_record(
        collection, metadata, 1, {} if force else schema)

    try:
        record = Record.create(data, id_=recid)
        # Invenio-Indexer is delegating the document inferring to
        # Invenio-Search which is analysing the string splitting by `/` and
        # using `.json` to be sure that it cans understand the mapping.
        record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

        indexer = RecordIndexer()
        indexer.index(record)

        # Creating permission needs for the record
        action_edit_record = RecordUpdateActionNeed(str(recid))
        action_read_record = RecordReadActionNeed(str(recid))
        action_index_record = RecordIndexActionNeed(str(recid))

        # Giving index, read, write permissions to user/creator
        db.session.add(ActionUsers.allow(action_edit_record))
        db.session.add(ActionUsers.allow(action_read_record))
        db.session.add(ActionUsers.allow(action_index_record))

        db.session.commit()

        print("DONE!!!")

    except ValidationError as error:
        print("============================")
        pprint(error.message)
        pprint(error.path)
        print("============================")

        db.session.rollback()
Beispiel #31
0
    def _add_user_permissions(self, user, permissions, session):
        """Adds permissions for user for this deposit."""
        for permission in permissions:
            session.add(
                ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
                                  user=user))

            session.flush()

            self['_access'][permission]['users'].append(user.id)
Beispiel #32
0
    def _add_experiment_permissions(self, experiment, permissions):
        """Add read permissions to everybody assigned to experiment."""
        exp_need = exp_need_factory(experiment)

        # give read access to members of collaboration
        with db.session.begin_nested():
            for au in ActionUsers.query_by_action(exp_need).all():
                self._add_user_permissions(au.user, permissions, db.session)
            for ar in ActionRoles.query_by_action(exp_need).all():
                self._add_egroup_permissions(ar.role, permissions, db.session)
Beispiel #33
0
def test_file_permissions(app, db, test_object,  # fixtures
                          user, access_right, expected):
    """Test file permissions."""
    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(
        ActionUsers.allow(ActionNeed('admin-access'), user=admin)
    )

    # Create test record
    rec_uuid = uuid.uuid4()
    PersistentIdentifier.create(
        'recid',
        '1',
        object_type='rec',
        object_uuid=rec_uuid,
        status=PIDStatus.REGISTERED
    )
    Record.create({
        'recid': 1,
        'owners': [2],
        'access_right': access_right,
        '_files': [
            {
                'key': test_object.key,
                'bucket': str(test_object.bucket_id),
                'checksum': 'invalid'
            },
        ]
    }, id_=rec_uuid)
    db.session.add(
        RecordsBuckets(record_id=rec_uuid, bucket_id=test_object.bucket_id)
    )

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value='1',
        filename=test_object.key
    )

    db.session.commit()

    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
def add_record(metadata, collection, schema, force):
    """Add record."""

    collection = Collection.query.filter(Collection.name == collection).first()

    if collection is None:
        return

    data, pid, recid = construct_record(collection, metadata, 1,
                                        {} if force else schema)

    try:
        record = Record.create(data, id_=recid)
        # Invenio-Indexer is delegating the document inferring to
        # Invenio-Search which is analysing the string splitting by `/` and
        # using `.json` to be sure that it cans understand the mapping.
        record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

        indexer = RecordIndexer()
        indexer.index(record)

        # Creating permission needs for the record
        action_edit_record = RecordUpdateActionNeed(str(recid))
        action_read_record = RecordReadActionNeed(str(recid))
        action_index_record = RecordIndexActionNeed(str(recid))

        # Giving index, read, write permissions to user/creator
        db.session.add(ActionUsers.allow(action_edit_record))
        db.session.add(ActionUsers.allow(action_read_record))
        db.session.add(ActionUsers.allow(action_index_record))

        db.session.commit()

        print("DONE!!!")

    except ValidationError as error:
        print("============================")
        pprint(error.message)
        pprint(error.path)
        print("============================")

        db.session.rollback()
Beispiel #35
0
def users(app, db):
    """Create users."""
    user1 = create_test_user(email='*****@*****.**', password='******')
    user2 = create_test_user(email='*****@*****.**', password='******')
    user_admin = create_test_user(email='*****@*****.**',
                                  password='******')

    with db.session.begin_nested():
        # set admin permissions
        db.session.add(ActionUsers(action=action_admin_access.value,
                                   user=user_admin))
        db.session.add(ActionUsers(action=deposit_admin_access.value,
                                   user=user_admin))
    db.session.commit()

    return [
        {'email': user1.email, 'id': user1.id},
        {'email': user2.email, 'id': user2.id},
        {'email': user_admin.email, 'id': user_admin.id}
    ]
Beispiel #36
0
 def update_permission(self, allow, community_id=None):
     with db.session.begin_nested():
         user = accounts.datastore.get_user(self.user_id)
         # only add the access rights if the access control is enabled
         if not app.extensions[
                 'b2share-communities'].rest_access_control_disabled:
             db.session.add(
                 ActionUsers(action=communities_update_all.value,
                             argument=str(community_id),
                             user=user,
                             exclude=not allow))
Beispiel #37
0
def test_monitoring_check_es_db_counts(app, client, contribution_person_data,
                                       system_librarian_martigny):
    """Test monitoring check_es_db_counts."""
    res = client.get(url_for('api_monitoring.check_es_db_counts', delay=0))
    assert res.status_code == 200
    assert get_json(res) == {'data': {'status': 'green'}}

    pers = Contribution.create(data=contribution_person_data,
                               delete_pid=False,
                               dbcommit=True,
                               reindex=False)
    flush_index(ContributionsSearch.Meta.index)
    res = client.get(url_for('api_monitoring.check_es_db_counts', delay=0))
    assert res.status_code == 200
    assert get_json(res) == {
        'data': {
            'status': 'red'
        },
        'errors': [{
            'code': 'DB_ES_COUNTER_MISSMATCH',
            'details': 'There are 1 items from cont missing in ES.',
            'id': 'DB_ES_COUNTER_MISSMATCH',
            'links': {
                'about': 'http://localhost/monitoring/check_es_db_counts',
                'cont': 'http://localhost/monitoring/missing_pids/cont'
            },
            'title': "DB items counts don't match ES items count."
        }]
    }

    # this view is only accessible by monitoring
    res = client.get(url_for('api_monitoring.missing_pids', doc_type='cont'))
    assert res.status_code == 401

    login_user_via_session(client, system_librarian_martigny.user)
    res = client.get(url_for('api_monitoring.missing_pids', doc_type='cont'))
    assert res.status_code == 403

    # give user superuser admin rights
    db.session.add(
        ActionUsers.allow(superuser_access,
                          user=system_librarian_martigny.user))
    db.session.commit()
    res = client.get(
        url_for('api_monitoring.missing_pids', doc_type='cont', delay=0))
    assert res.status_code == 200

    assert get_json(res) == {
        'data': {
            'DB': [],
            'ES': ['http://localhost/contributions/cont_pers'],
            'ES duplicate': []
        }
    }
def create_user_with_access(username, action):
    user = _datastore.find_user(email=username)

    if not user:
        user = create_test_user(email=username, password='******')

    db_.session.add(ActionUsers.allow(
        ActionNeed(action), user=user))

    db_.session.commit()

    return user
Beispiel #39
0
    def _make_user(role_name, organisation='org'):
        make_organisation(organisation)

        name = role_name
        if organisation:
            name = organisation + name

        email = '{name}@rero.ch'.format(name=name)

        datastore = app.extensions['security'].datastore

        user = datastore.find_user(email=email)

        if user:
            record = UserRecord.get_user_by_email(email)
            return record

        user = datastore.create_user(email=email,
                                     password=hash_password('123456'),
                                     active=True)
        datastore.commit()

        role = datastore.find_role(role_name)
        if not role:
            role = Role(name=role_name)

        role.users.append(user)

        db.session.add(role)
        db.session.add(
            ActionUsers.allow(ActionNeed(
                '{role}-access'.format(role=role_name)),
                              user=user))
        db.session.commit()

        record = UserRecord.create(
            {
                'pid': name,
                'email': email,
                'full_name': name,
                'roles': [role_name],
                'organisation': {
                    '$ref':
                    'https://sonar.ch/api/organisations/{organisation}'.format(
                        organisation=organisation)
                }
            },
            dbcommit=True)
        record.reindex()
        db.session.commit()

        return record
def change_record_privacy(pid_value=None):
    resolver = Resolver(
        pid_type='recid',
        object_type='rec',
        getter=Record.get_record)

    pid, record = resolver.resolve(pid_value)

    permission_update_record = update_permission_factory(record)
    if not permission_update_record.can():
        abort(403)

    index_instance = ActionUsers.query.filter(
        ActionUsers.action == "records-index",
        ActionUsers.argument == str(record.id),
        ActionUsers.user_id.is_(None)).first()

    read_instance = ActionUsers.query.filter(
        ActionUsers.action == "records-read",
        ActionUsers.argument == str(record.id),
        ActionUsers.user_id.is_(None)).first()

    with db.session.begin_nested():
        if index_instance:
            db.session.delete(index_instance)
            db.session.delete(read_instance)
        else:
            action_read_record = RecordReadActionNeed(str(record.id))
            action_index_record = RecordIndexActionNeed(str(record.id))
            db.session.add(ActionUsers.allow(action_read_record))
            db.session.add(ActionUsers.allow(action_index_record))

    db.session.commit()

    resp = jsonify()
    resp.status_code = 200
    return resp
    def _add_user_permissions(self,
                              user,
                              permissions,
                              session):
        """Adds permissions for user for this deposit."""
        for permission in permissions:
            session.add(
                ActionUsers.allow(
                    DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
                    user=user
                )
            )

            session.flush()

            self['_access'][permission]['users'].append(user.id)
Beispiel #42
0
def create_user(name, roles=None, permissions=None, admin_communities=None,
                member_communities=None):
    """Create a user.

    Args:
        name (str): user's name.
        roles (list): roles assigned to this new user.

    Returns:
        (UserInfo) created user's information.
    """

    users_password = '******'
    accounts = current_app.extensions['invenio-accounts']
    security = current_app.extensions['security']

    email = '{}@example.org'.format(name)
    with db.session.begin_nested():
        user = accounts.datastore.create_user(
            email=email,
            password=hash_password(users_password),
            active=True,
        )
        db.session.add(user)

        if roles is not None:
            for role in roles:
                security.datastore.add_role_to_user(user, role)

        if permissions is not None:
            for permission in permissions:
                # permissions of the form [('action name', 'argument'), (...)]
                if len(permission) == 2:
                    permission = ParameterizedActionNeed(permission[0],
                                                         permission[1])
                db.session.add(ActionUsers.allow(permission, user=user))

    return UserInfo(email=email, password=users_password, id=user.id)
def set_user_permissions(user, permissions, id, session, access):
    _permissions = (p for p in permissions if p.get(
        "action", "") in DEPOSIT_ACTIONS)

    for permission in _permissions:

        if (permission.get("op", "") == "add"):
            try:
                session.add(ActionUsers.allow(
                    DEPOSIT_ACTIONS_NEEDS(id).get(
                        permission.get("action", ""),
                        ""),
                    user=user
                ))
            except:
                return

            access.get(permission["action"], {}).get(
                'user', []).append(user.id)

        elif (permission.get("op", "") == "remove"):
            try:
                au = ActionUsers.query.filter(
                    ActionUsers.action == permission.get("action", ""),
                    ActionUsers.argument == str(id),
                    ActionUsers.user_id == user.id).first()

                if au:
                    session.delete(au)

            except:
                return

            access.get(permission["action"], {}).get(
                'user', []).remove(user.id)

    return access
Beispiel #44
0
def test_file_permissions(app, db, record_with_files_creation,
                          user, access_right, expected):
    """Test file permissions."""
    pid, record, record_url = record_with_files_creation

    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(
        ActionUsers.allow(ActionNeed('admin-access'), user=admin)
    )
    db.session.commit()

    # Create test record
    record['access_right'] = access_right
    record['owners'] = [owner.id]
    record.commit()
    db.session.commit()

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value=pid.pid_value,
        filename='Test.pdf',
    )
    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
    def _add_deposit_permissions(cls, data, id_):
        """Inherit permissions after deposit."""
        data['_access'] = {
            DEPOSIT_TO_RECORD_ACTION_MAP[action]: permission
            for action, permission in data['_access'].items()
        }

        for action, permission in data['_access'].items():
            for role in permission['roles']:
                role = Role.query.filter_by(id=role).one()
                db.session.add(
                    ActionRoles.allow(
                        RECORD_ACTION_NEEDS(id_)[action],
                        role=role
                    )
                )
            for user in permission['users']:
                user = User.query.filter_by(id=user).one()
                db.session.add(
                    ActionUsers.allow(
                        RECORD_ACTION_NEEDS(id_)[action],
                        user=user
                    )
                )
def add_record(metadata, collection, schema, force, files=[]):
    """Add record."""

    collection = Collection.query.filter(
        Collection.name == collection).first()

    if collection is None:
        return

    data, pid, recid = construct_record(
        collection, metadata, 1, {} if force else schema)
    d = current_app.config['DATADIR']

    buckets = []
    data['_files'] = []

    for file in files:
        bucket = Bucket.create(default_location=Location.get_default())
        buckets.append(bucket)

        with open(pkg_resources.resource_filename(
                'cap.modules.fixtures', os.path.join('data', 'files', file)
        ), 'rb') as fp:
            obj = ObjectVersion.create(bucket, file, stream=fp)

            data['_files'].append({
                'bucket': str(obj.bucket_id),
                'key': obj.key,
                'size': obj.file.size,
                'checksum': str(obj.file.checksum),
                'version_id': str(obj.version_id),
            })
    try:
        record = Record.create(data, id_=recid)

        for bucket in buckets:
            rb = RecordsBuckets(record_id=record.id, bucket_id=bucket.id)
            db.session.add(rb)

        # Invenio-Indexer is delegating the document inferring to
        # Invenio-Search which is analysing the string splitting by `/` and
        # using `.json` to be sure that it cans understand the mapping.
        record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

        indexer = RecordIndexer()
        indexer.index(record)

        # Creating permission needs for the record
        action_edit_record = RecordUpdateActionNeed(str(recid))
        action_read_record = RecordReadActionNeed(str(recid))
        action_index_record = RecordIndexActionNeed(str(recid))

        # Giving index, read, write permissions to user/creator
        db.session.add(ActionUsers.allow(action_edit_record))
        db.session.add(ActionUsers.allow(action_read_record))
        db.session.add(ActionUsers.allow(action_index_record))

        db.session.commit()

        print("DONE!!!")

    except ValidationError as error:
        print("============================")
        pprint(error.message)
        pprint(error.path)
        print("============================")

        db.session.rollback()
def update_record_permissions(pid_value=None):
    resolver = Resolver(
        pid_type='recid',
        object_type='rec',
        getter=Record.get_record)

    pid, record = resolver.resolve(pid_value)


    emails = []
    roles = []
    userrole_list = request.get_json().keys()

    if not (current_app.config.get('EMAIL_REGEX', None)):
        resp = jsonify(**{message: "ERROR in email regex ;)"})
        resp.status_code = 400
        return resp

    email_regex = re.compile(current_app.config.get('EMAIL_REGEX'), )

    for userrole in userrole_list:
        if email_regex.match(userrole):
            emails.append(userrole)
        else:
            #: [TOBEFIXED] Needs to check if E-Group exists
            try:
                role = Role.query.filter(Role.name == userrole).first()
                if not role:
                    tmp_role = _datastore.create_role(name=userrole)
                roles.append(userrole)
            except:
                print("Something happened when trying to create '"+userrole+"' role")
            # Role.add(tmp_role)

    users = User.query.filter(User.email.in_(emails)).all()
    roles = Role.query.filter(Role.name.in_(roles)).all()

    action_edit_record = RecordUpdateActionNeed(str(record.id))
    action_read_record = RecordReadActionNeed(str(record.id))
    action_index_record = RecordIndexActionNeed(str(record.id))

    with db.session.begin_nested():
        for user in users:
            for action in request.get_json().get(user.email, None):
                if (action.get("action", None) == "records-read" and action.get("op", None) == "add"):
                    db.session.add(ActionUsers.allow(action_read_record, user=user))
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "add"):
                    db.session.add(ActionUsers.allow(action_index_record, user=user))
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "add"):
                    db.session.add(ActionUsers.allow(action_edit_record, user=user))
                elif (action.get("action", None) == "records-read" and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(ActionUsers.action == "records-read", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(ActionUsers.action == "records-index", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(ActionUsers.action == "records-update", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)

        # db.session.begin(nested=True)
        for role in roles:
            for action in request.get_json().get(role.name, None):
                if (action.get("action", None) == "records-read" and action.get("op", None) == "add"):
                    db.session.add(ActionRoles.allow(action_read_record, role=role))
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "add"):
                    db.session.add(ActionRoles.allow(action_index_record, role=role))
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "add"):
                    db.session.add(ActionRoles.allow(action_edit_record, role=role))
                elif (action.get("action", None) == "records-read" and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(ActionRoles.action == "records-read", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(ActionRoles.action == "records-index", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(ActionRoles.action == "records-update", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)

    db.session.commit()

    resp = jsonify()
    resp.status_code = 200
    return resp
def delete_record_read_permissions(recid=None, user=None):
    action_read_record = RecordReadActionNeed(str(recid))
    db.session.delete(ActionUsers.allow(action_read_record, user=user))
def add_record_edit_permissions(recid=None, user=None):
    action_edit_record = RecordUpdateActionNeed(str(recid))
    db.session.add(ActionUsers.allow(action_edit_record, user=user))
def add_record_index_permissions(recid=None, user=None):
    action_index_record = RecordIndexActionNeed(str(recid))
    db.session.add(ActionUsers.allow(action_index_record, user=user))