Ejemplo n.º 1
0
def owner_permission_factory(record=None):
    """Permissions factory for record owners."""
    # TODO: adapt for more owners
    owners = _get_owners(record)
    if len(owners) > 0:
        return Permission(UserNeed(int(owners[0])))
    return Permission(UserNeed(-1))
Ejemplo n.º 2
0
def test_record_owner(app, mocker):
    generator = RecordOwners()
    record = _owned_record()

    assert generator.needs(record=record) == [
        UserNeed(16),
        UserNeed(17),
    ]

    assert generator.excludes(record=record) == []

    # Anonymous identity.
    assert not generator.query_filter(identity=mocker.Mock(provides=[]))

    # Authenticated identity
    query_filter = generator.query_filter(
        identity=mocker.Mock(
            provides=[mocker.Mock(method='id', value=15)]
        )
    )

    expected_query_filter = {
        "terms": {
            "parent.access.owned_by.user": [15]
        }
    }
    assert query_filter.to_dict() == expected_query_filter
Ejemplo n.º 3
0
def populate_identity_roles(identity, user=None):
    identity.user = user

    if user is None or user.is_anonymous:
        if current_app.config['POLICY_ANONYMOUS_VIEW_INDEX']:
            identity.provides.add(roles.index_view)
        if current_app.config['POLICY_ANONYMOUS_VIEW_POST']:
            identity.provides.add(roles.post_view)
        if current_app.config['POLICY_ANONYMOUS_VIEW_STATS']:
            identity.provides.add(roles.stats_view)
        if current_app.config['POLICY_ANONYMOUS_DOWNLOADS']:
            identity.provides.add(roles.post_download)

    # This user identifier from google shouldn't be spoofable.
    # And `@` is not a valid email character, except as delimiter b/w domain.
    # SECURITY WARNING: THIS ASSUMES `user.identifier` IS A GOOGLE EMAIL.
    # ONLY GOOGLE MUST BE THE AUTHENTICATION METHOD.
    elif any(
            user.identifier.endswith("@" + domain)
            for domain in current_app.config['USER_IDENTIFIER_DOMAINS']):
        identity.provides.add(UserNeed(user.identifier))
        identity.provides.add(roles.index_view)
        identity.provides.add(roles.post_view)
        identity.provides.add(roles.post_edit)
        identity.provides.add(roles.post_comment)
        identity.provides.add(roles.post_download)
        identity.provides.add(roles.stats_view)

        # TODO: Populate group permissions, and port existing group admin
        # code to roles.
    else:
        identity.provides.add(UserNeed(user.identifier))
        identity.provides.add(roles.stats_view)

    return identity
Ejemplo n.º 4
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)))
Ejemplo n.º 5
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)
Ejemplo n.º 6
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([])
        )
Ejemplo n.º 7
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)
        superuser = User(email='*****@*****.**')
        user_can_all = User(email='*****@*****.**')
        user_can_read = User(email='*****@*****.**')
        user_can_open = User(email='*****@*****.**')

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

        db.session.add(ActionUsers(action='superuser-access', user=superuser))

        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.add(ActionUsers(action='not_logged', user=user_can_all))

        db.session.commit()

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

        identity_superuser = FakeIdentity(UserNeed(superuser.id))
        identity_all = FakeIdentity(UserNeed(user_can_all.id))
        identity_read = FakeIdentity(UserNeed(user_can_read.id))
        identity_open = FakeIdentity(UserNeed(user_can_open.id))
        identity_unknown = AnonymousIdentity()

        # global permissions
        assert permission_open.allows(identity_superuser)
        assert permission_read.allows(identity_superuser)

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

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

        assert not permission_open.allows(identity_read)
        assert permission_read.allows(identity_read)
        assert not permission_not_logged.allows(identity_read)

        assert not permission_open.allows(identity_unknown)
        assert not permission_read.allows(identity_unknown)
Ejemplo n.º 8
0
def test_deny_by_user_id(access_app):
    """Ensure deny permission when user is denied."""
    admin, reader = create_users("admin", "reader")

    permission, = create_permissions(
        {"excludes": [UserNeed(admin.id),
                      UserNeed(reader.id)]})

    assert not permission.allows(admin)
    assert not permission.allows(reader)
    assert permission.allows(get_superuser())
Ejemplo n.º 9
0
 def record_needs(self):
     """Create needs of the record."""
     needs = []
     for access_entity in self.record_allows():
         try:
             if isinstance(access_entity, string_types):
                 needs.append(UserNeed(int(access_entity)))
             elif isinstance(access_entity, int):
                 needs.append(UserNeed(access_entity))
         except ValueError:
             needs.append(RoleNeed(access_entity.lower()))
     return needs
Ejemplo n.º 10
0
def test_update_permission_factory(app, mocker, record, superuser_role_need):
    patched_g = mocker.patch('invenio_records_permissions.generators.g')
    patched_g.identity.provides = [mocker.Mock(method='id', value=4)]

    permission = record_update_permission_factory(record)

    assert permission.needs == {
        superuser_role_need,
        UserNeed(1),
        UserNeed(2),
        UserNeed(3)
    }
    assert permission.excludes == set()
Ejemplo n.º 11
0
def test_allow_deny_by_user_id(access_app):
    """Ensure allow/deny permission when same user is allowed and denied."""
    admin, reader = create_users("admin", "reader")

    permission, = create_permissions({
        "needs": [UserNeed(admin.id)],
        "excludes": [UserNeed(admin.id),
                     UserNeed(reader.id)],
    })

    # `excludes` prevail over `needs`
    assert not permission.allows(admin)
    assert not permission.allows(reader)
    assert permission.allows(get_superuser())
Ejemplo n.º 12
0
 def check_perm():
     is_perm_required = Permission.query.filter_by(
         content_type=request.path).first()
     if is_perm_required:
         permissions = set()
         perm_users = db.session.query(UserPermission.uid)\
             .join(Permission, UserPermission.pid == Permission.id)\
             .filter(Permission.content_type == request.path).all()
         admins = db.session.query(User.id).filter_by(role_id=ADMIN).all()
         for user in perm_users:
             permissions.add(UserNeed(user.uid))
         for user in admins:
             permissions.add(UserNeed(user.id))
         if not PrincipalPermission(*permissions).can():
             raise PermissionDenied('PermissionDenied.')
Ejemplo n.º 13
0
    def on_identity_loaded(sender, identity):
        '''基础权限'''
        identity.user = current_user

        if hasattr(current_user, 'id'):
            identity.provides.add(UserNeed(current_user.id))

        if hasattr(current_user, 'is_superuser'):
            if current_user.is_superuser:
                identity.provides.add(RoleNeed('super'))

        if hasattr(current_user, 'is_confirmed'):
            if current_user.is_confirmed:
                identity.provides.add(RoleNeed('confirmed'))

        if hasattr(current_user, 'is_authenticated'):
            if current_user.is_authenticated:
                identity.provides.add(RoleNeed('auth'))
            else:
                identity.provides.add(RoleNeed('guest'))

        if hasattr(current_user, 'topics'):
            for topic in current_user.topics:
                identity.provides.add(TopicNeed(topic.id))

        if hasattr(current_user, 'replies'):
            for reply in current_user.replies:
                identity.provides.add(ReplyNeed(reply.id))

        if hasattr(current_user, 'collects'):
            for collect in current_user.collects:
                identity.provides.add(CollectNeed(collect.id))
Ejemplo n.º 14
0
        def test_permissions():
            """Iterates over all users checking its permissions."""
            for i in range(users_number):
                identity = FakeIdentity(UserNeed(users[i].id))

                # Allowed permission
                permission_allowed_both = DynamicPermission(
                    ActionNeed('action{0}'.format(
                        (i % actions_users_number) +
                        actions_roles_number)),
                    ActionNeed('action{0}'.format(i % actions_roles_number))
                )
                assert permission_allowed_both.allows(identity)

                # Not allowed action user
                permission_not_allowed_user = DynamicPermission(
                    ActionNeed('action{0}'.format(
                        (i + 1) % actions_users_number +
                        actions_roles_number))
                )
                assert not permission_not_allowed_user.allows(identity)

                # Not allowed action role
                permission_not_allowed_role = DynamicPermission(
                    ActionNeed('action{0}'.format(
                        (i + 1) % actions_roles_number))
                )
                assert not permission_not_allowed_role.allows(identity)
Ejemplo n.º 15
0
def update_user():
    """Update current logged user
    """
    user = current_user
    form = UserForm(request.form, obj=user)
    del form.role
    del form.is_active

    perm = Permission(UserNeed(user.id), RoleNeed('admin'))
    perm.test()

    if form.validate_on_submit():
        if form.username.data != user.username and User.username_is_in_use(
                form.username.data):
            flash(
                "This username is already been used. Please choose another one!",
                "alert-danger")
            form.username.errors.append('Please correct this field')
        elif form.email.data != user.email and User.email_is_in_use(
                form.email.data):
            flash(
                "This email is already been used. Please choose another one!",
                "alert-danger")
            form.email.errors.append('Please correct this field')
        else:
            form.populate_obj(user)
            db.session.commit()
            flash("Informations updated", "alert-info")
            return redirect(url_for('dashboard.index'))

    return render_template("user/update.html", form=form, user=current_user)
Ejemplo n.º 16
0
 def provides(self):
     needs = [RoleNeed('authenticated'), UserNeed(self.id)]
     if self.is_member:
         needs.append(RoleNeed('member'))
     if self.is_admin:
         needs.append(RoleNeed('admin'))
     return needs
Ejemplo n.º 17
0
def identity():
    """Identity fixture with rights to interact with service."""
    i = Identity(1)
    i.provides.add(UserNeed(1))
    i.provides.add(any_user)
    i.provides.add(system_process)
    return i
Ejemplo n.º 18
0
    def __init__(self, record=None, previous_record=None):
        """Constructor.

        Args:
            record: data submitted for the new deposit
        """
        super(CreateDepositPermission, self).__init__()
        self.record = record
        if record is not None:
            needs = set()
            community = Community.get(record['community'])
            publication_state = record.get('publication_state', 'draft')
            if publication_state != 'draft' or community.restricted_submission:
                needs.add(create_deposit_need_factory())
                needs.add(create_deposit_need_factory(
                    community=record['community'],
                    publication_state=publication_state,
                ))
            elif not community.restricted_submission:
                needs.add(AuthenticatedNeed)

            self.permissions.add(StrictDynamicPermission(*needs))
            if previous_record:
                # we allow only the owner of a record to
                # create a new version of it.
                needs = set()
                for owner_id in previous_record['_deposit']['owners']:
                    needs.add(UserNeed(owner_id))
                self.permissions.add(StrictDynamicPermission(*needs))
Ejemplo n.º 19
0
    def __init__(self, deposit, new_state=None):
        """Constructor

        Args:
            deposit (Deposit): deposit which is modified.
            new_state (str): new publication state of the deposit
                if applicable.
        """
        super(UpdateDepositMetadataPermission, self).__init__()
        # Owners are allowed to update
        for owner_id in deposit['_deposit']['owners']:
            self.explicit_needs.add(UserNeed(owner_id))

        # authorize if the user can modify metadata in the old
        # publication state
        self.explicit_needs.add(
            update_deposit_metadata_need_factory(
                community=deposit['community'],
                publication_state=deposit['publication_state']
            )
        )
        # authorize if the user can modify metadata in the new
        # publication state
        if new_state != deposit['publication_state']:
            self.explicit_needs.add(
                update_deposit_metadata_need_factory(
                    community=deposit['community'],
                    publication_state=new_state
                )
            )
Ejemplo n.º 20
0
def identity_simple(users):
    """Simple identity fixture."""
    user = users[0]
    i = Identity(user.id)
    i.provides.add(UserNeed(user.id))
    i.provides.add(Need(method='system_role', value='any_user'))
    return i
Ejemplo n.º 21
0
def update_user(user=None):
    """
    Install the user as current user of the app.

    Setup the g.current_user variable.
    Add the user to the session.
    Update Flask-Principal.

    If no user, install AnonymousIdentity
    """
    if user:
        db.session.add(user)
        db.session.commit()
        g.current_user = user

        # Tell Flask-Principal the identity changed
        identity = Identity(user.id)
        identity.user = user

        # By default we can self need
        identity.provides.add(UserNeed(user.id))

        # Add roles
        for role in user.roles:
            identity.provides.add(RoleNeed(role.name))

        identity_changed.send(current_app._get_current_object(),
                              identity=identity)
    else:
        # Tell Flask-Principal the user is anonymous
        identity_changed.send(current_app._get_current_object(),
                              identity=AnonymousIdentity())
Ejemplo n.º 22
0
def test_load_permissions_on_identity_loaded(app):
    """Check that the needs are loaded properly in the user Identity."""
    InvenioAccess(app)

    with app.test_request_context():
        identity_changed.send(current_app._get_current_object(),
                              identity=AnonymousIdentity())
        assert g.identity.provides == {any_user}

    with app.test_request_context():
        user = testutils.create_test_user('*****@*****.**')
        login_user(user)
        assert g.identity.provides == {
            any_user, authenticated_user, UserNeed(user.id)
        }
        logout_user()
        # FIXME: The user is still authenticatd when the identity loader
        # is called during logout. We could filter on AnonymousIdentity, but
        # This would be inconsistent as the UserNeed(user.id) is still there.
        # This will pass even if it is unexpected:
        # assert g.identity.provides == {
        #     any_user, authenticated_user, UserNeed(user.id)
        # }
        # Forcing the identity to reload again cleans the mess. In practice
        # this won't be needed as the identity is reloaded between requests.
        identity_changed.send(current_app._get_current_object(),
                              identity=AnonymousIdentity())
        assert g.identity.provides == {any_user}
Ejemplo n.º 23
0
def extend_identity(identity, groups):
    """Extend identity with roles based on CERN groups."""
    provides = set([UserNeed(current_user.email)] + [
        RoleNeed('{0}@cern.ch'.format(name)) for name in groups
    ])
    identity.provides |= provides
    session[OAUTHCLIENT_CERN_SESSION_KEY] = provides
def on_identity_loaded(sender, identity):
    # Set the identity user object
    identity.user = current_user

    # Add the UserNeed to the identity
    if hasattr(current_user, 'id'):
        identity.provides.add(UserNeed(current_user.id))
Ejemplo n.º 25
0
def edit_post(id):

    post = Post.query.get_or_404(id)
    permission = Permission(UserNeed(post.author.id))
    # 设置访问本视图的权限

    if permission.can() or admin_permission.can():
        # 判断Identity是否有要求的permission
        form = PostForm()

        if form.validate_on_submit():
            post.title = form.title.data
            post.text = form.text.data
            post.publish_date = datetime.datetime.now()

            db.session.add(post)
            db.session.commit()

            return redirect(url_for('blog.post', post_id=post.id))

        form.text.data = post.text

        return render_template('blog/edit.html', form=form, post=post)

    abort(403)
Ejemplo n.º 26
0
def identity():
    """Simple identity to interact with the service."""
    i = Identity(1)
    i.provides.add(UserNeed(1))
    i.provides.add(any_user)
    i.provides.add(system_process)
    return i
def test_allowedbyaccesslevels_metadata_curator(action, create_record):
    # Restricted record, only viewable by owner and a Metadata Curator
    record = create_record({
        "owners": [4],
        "_access": {
            "metadata_restricted": True,
            "files_restricted": True
        },
        "internal": {
            "access_levels": {
                "metadata_curator": [{
                    "scheme": "person",
                    "id": 1
                }]
            }
        },
    })
    generator = AllowedByAccessLevel(action=action)

    if action in ["read", "update"]:
        assert generator.needs(record=record) == [UserNeed(1)]
    else:
        assert generator.needs(record=record) == []

    assert generator.excludes(record=record) == []
Ejemplo n.º 28
0
 def on_identity_loaded(sender, identity):
     identity.user = current_user
     if hasattr(current_user, 'id'):
         identity.provides.add(UserNeed(current_user.id))
     if hasattr(current_user, 'roles'):
         for role in current_user.roles:
             identity.provides.add(RoleNeed(role.name))
Ejemplo n.º 29
0
def on_identity_loaded(sender, identity):
    """
    Sets the identity of a given option, assigns additional permissions based on
    the role that the user is a part of.

    :param sender:
    :param identity:
    """
    # load the user
    user = user_service.get(identity.id)

    # add the UserNeed to the identity
    identity.provides.add(UserNeed(identity.id))

    # identity with the roles that the user provides
    if hasattr(user, 'roles'):
        for role in user.roles:
            identity.provides.add(RoleNeed(role.name))
            identity.provides.add(RoleMemberNeed(role.id))

    # apply ownership for authorities
    if hasattr(user, 'authorities'):
        for authority in user.authorities:
            identity.provides.add(AuthorityCreatorNeed(authority.id))

    g.user = user
Ejemplo n.º 30
0
def edit_post(id):
    post = Post.query.get_or_404(id)

    #保证用户市登录的
    if not current_user:
        return redirect(url_for('main.login'))

    if current_user != post.users:
        return redirect(url_for('blog.post', post_id=id))

    #当user是poster或者admin,才可以编辑文章
    permission = Permission(UserNeed(post.users.id))
    if permission.can() or admin_permission.can():
        form = PostForm()

        if form.validate_on_submit():
            post.title = form.title.data
            post.text = form.text.data
            post.published_date = datetime.now()

            db.session.add(post)
            db.session.commit()
            return redirect(url_for('blog.post', post_id=post.id))
        else:
            abort(403)

        form.title.data = post.title
        form.text.data = post.text
        return render_template('edit_post.html', form=form, post=post)