예제 #1
0
def test_init():
    """Test extension initialization."""
    app = Flask('testapp')
    if not hasattr(app, 'cli'):
        from flask_cli import FlaskCLI
        FlaskCLI(app)
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess(app)
    assert 'invenio-access' in app.extensions

    app = Flask('testapp')
    if not hasattr(app, 'cli'):
        from flask_cli import FlaskCLI
        FlaskCLI(app)
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess()
    assert 'invenio-access' not in app.extensions
    ext.init_app(app)
    assert 'invenio-access' in app.extensions
예제 #2
0
def script_info_cli_list(request):
    """Get ScriptInfo object for testing CLI list command."""
    app_ = app(request)
    access = InvenioAccess(app_)
    access.register_action(ActionNeed('open'))
    access.register_action(ActionNeed('read'))

    return ScriptInfo(create_app=lambda info: app_)
예제 #3
0
def script_info(request):
    """Get ScriptInfo object for testing CLI."""
    action_open = ActionNeed('open')
    action_edit = ParameterizedActionNeed('edit', None)

    app_ = app(request)
    ext = InvenioAccess(app_)
    ext.register_action(action_open)
    ext.register_action(action_edit)
    return ScriptInfo(create_app=lambda info: app_)
def test_actions():
    """Test if the actions are registered properly."""
    app = Flask('testapp')
    FlaskCLI(app)
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess()
    ext.register_action(ActionNeed('action_a'))
    assert len(ext.actions) == 1
    ext.register_action(ActionNeed('action_b'))
    assert len(ext.actions) == 2
def test_init():
    """Test extension initialization."""
    app = Flask("testapp")
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess(app)
    assert "invenio-access" in app.extensions

    app = Flask("testapp")
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess()
    assert "invenio-access" not in app.extensions
    ext.init_app(app)
    assert "invenio-access" in app.extensions
def test_init():
    """Test extension initialization."""
    app = Flask('testapp')
    FlaskCLI(app)
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess(app)
    assert 'invenio-access' in app.extensions

    app = Flask('testapp')
    FlaskCLI(app)
    Babel(app)
    Mail(app)
    InvenioDB(app)
    InvenioAccounts(app)
    ext = InvenioAccess()
    assert 'invenio-access' not in app.extensions
    ext.init_app(app)
    assert 'invenio-access' in app.extensions
예제 #7
0
app = Flask(__name__)
app.config.update({
    'SQLALCHEMY_TRACK_MODIFICATIONS': False,
})
app.secret_key = 'ExampleApp'
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get(
    'SQLALCHEMY_DATABASE_URI', 'sqlite:///instance/test.db'
)
Babel(app)
Mail(app)
Menu(app)
InvenioDB(app)
InvenioAccounts(app)
app.register_blueprint(blueprint_accounts)

access = InvenioAccess(app)

try:
    pkg_resources.get_distribution('invenio_admin')
    from invenio_admin import InvenioAdmin
    InvenioAdmin(app)
except pkg_resources.DistributionNotFound:
    pass

action_open = ActionNeed('open')
access.register_action(action_open)

action_read = ActionNeed('read')
access.register_action(action_read)

예제 #8
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        TESTING=True,
        SECRET_KEY='SECRET_KEY',
        ADMIN_LOGIN_ENDPOINT='login',
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
    )
    Babel(app)
    InvenioDB(app)
    InvenioAccess(app)
    Principal(app)
    LoginManager(app)
    Menu(app)

    # Install login and access loading.
    @app.login_manager.user_loader
    def load_user(user_id):
        return TestUser.get(user_id)

    @app.route('/login/')
    def login():
        from flask import current_app
        from flask import request as flask_request
        user = TestUser.get(flask_request.args.get('user', 1))
        login_user(user)
        identity_changed.send(current_app._get_current_object(),
                              identity=Identity(user.id))
        return "Logged In"

    @identity_loaded.connect_via(app)
    def on_identity_loaded(sender, identity):
        identity.user = current_user
        identity.provides.add(UserNeed(current_user.id))
        if current_user.id == 1:
            identity.provides.add(action_admin_access)

    # Register admin view
    InvenioAdmin(app,
                 permission_factory=lambda x: Permission(action_admin_access))
    app.extensions['invenio-admin'].register_view(TestModelView, TestModel,
                                                  db.session)
    app.extensions['invenio-admin'].register_view(TestBase)
    app.register_blueprint(blueprint)

    # Create database
    with app.app_context():
        if not database_exists(str(db.engine.url)):
            create_database(str(db.engine.url))
        db.drop_all()
        db.create_all()

    def teardown():
        with app.app_context():
            drop_database(str(db.engine.url))
        shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    return app
예제 #9
0
def test_invenio_access_permission_cache_users_updates(app,
                                                       dynamic_permission):
    """Testing ActionUsers cache with inserts/updates/deletes."""
    cache = SimpleCache()
    InvenioAccess(app, cache=cache)
    with app.test_request_context():
        # Creation of some data to test.
        user_1 = User(email='*****@*****.**')
        user_2 = User(email='*****@*****.**')
        user_3 = User(email='*****@*****.**')
        user_4 = User(email='*****@*****.**')
        user_5 = User(email='*****@*****.**')
        user_6 = User(email='*****@*****.**')

        db.session.add(user_1)
        db.session.add(user_2)
        db.session.add(user_3)
        db.session.add(user_4)
        db.session.add(user_5)
        db.session.add(user_6)

        db.session.add(ActionUsers(action='open', user=user_1))
        db.session.add(ActionUsers(action='write', user=user_4))

        db.session.flush()

        # Creation identities to test.
        identity_user_1 = FakeIdentity(UserNeed(user_1.id))
        identity_user_2 = FakeIdentity(UserNeed(user_2.id))
        identity_user_3 = FakeIdentity(UserNeed(user_3.id))
        identity_user_4 = FakeIdentity(UserNeed(user_4.id))
        identity_user_5 = FakeIdentity(UserNeed(user_5.id))
        identity_user_6 = FakeIdentity(UserNeed(user_6.id))

        # Test if user 1 can open. In this case, the cache should store only
        # this object.
        permission_open = dynamic_permission(ActionNeed('open'))
        assert permission_open.allows(identity_user_1)
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1)]), set([]))

        # Test if user 4 can write. In this case, the cache should have this
        # new object and the previous one (Open is allowed to user_1)
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_user_4)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='id', value=4)]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1)]), set([]))

        # If we add a new user to the action open, the open action in cache
        # should be removed but it should still containing the write entry.
        db.session.add(ActionUsers(action='open', user=user_2))
        db.session.flush()
        assert current_access.get_action_cache('open') is None
        permission_open = dynamic_permission(ActionNeed('open'))
        assert permission_open.allows(identity_user_2)
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1),
             Need(method='id', value=2)]), set([]))
        assert current_access.get_action_cache('write') == (set(
            [Need(method='id', value=4)]), set([]))

        # Test if the new user is added to the action 'open'
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_user_4)
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1),
             Need(method='id', value=2)]), set([]))
        assert current_access.get_action_cache('write') == (set(
            [Need(method='id', value=4)]), set([]))

        # If we update an action swapping a user, the cache containing the
        # action, should be removed.
        user_4_action_write = ActionUsers.query.filter(
            ActionUsers.action == 'write'
            and ActionUsers.user == user_4).first()
        user_4_action_write.user = user_3
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1),
             Need(method='id', value=2)]), set([]))

        # Test if the user_3 can now write.
        permission_write = dynamic_permission(ActionNeed('write'))
        assert not permission_write.allows(identity_user_4)
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_user_3)
        assert current_access.get_action_cache('write') == (set(
            [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([]))

        # If we remove a user from an action, the cache should clear the
        # action item.
        user_3_action_write = ActionUsers.query.filter(
            ActionUsers.action == 'write'
            and ActionUsers.user == user_3).first()
        db.session.delete(user_3_action_write)
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        # If no one is allowed to perform an action then everybody is allowed.
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_user_3)
        assert current_access.get_action_cache('write') == (set([]), set([]))
        db.session.add(ActionUsers(action='write', user=user_5))
        db.session.flush()
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_user_5)
        permission_write = dynamic_permission(ActionNeed('write'))
        assert not permission_write.allows(identity_user_3)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='id', value=5)]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1),
             Need(method='id', value=2)]), set([]))

        # If you update the name of an existing action, the previous action
        # and the new action should be remove from cache.
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_user_5)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='id', value=5)]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [Need(method='id', value=1),
             Need(method='id', value=2)]), set([]))
        user_5_action_write = ActionUsers.query.filter(
            ActionUsers.action == 'write'
            and ActionUsers.user == user_5).first()
        user_5_action_write.action = 'open'
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        assert current_access.get_action_cache('open') is None
        permission_open = dynamic_permission(ActionNeed('open'))
        assert permission_open.allows(identity_user_1)
        assert current_access.get_action_cache('open') == (set([
            Need(method='id', value=1),
            Need(method='id', value=2),
            Need(method='id', value=5)
        ]), set([]))
        db.session.add(ActionUsers(action='write', user=user_4))
        permission_write = dynamic_permission(ActionNeed('write'))
        assert not permission_write.allows(identity_user_5)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='id', value=4)]), set([]))

        db.session.add(ActionUsers(action='open', argument='1', user=user_6))
        db.session.flush()
        permission_open_1 = dynamic_permission(
            ParameterizedActionNeed('open', '1'))
        assert not permission_open.allows(identity_user_6)
        assert permission_open_1.allows(identity_user_6)
        assert current_access.get_action_cache('open::1') == (set([
            Need(method='id', value=1),
            Need(method='id', value=2),
            Need(method='id', value=5),
            Need(method='id', value=6)
        ]), set([]))
        user_6_action_open_1 = ActionUsers.query.filter_by(
            action='open', argument='1', user_id=user_6.id).first()
        user_6_action_open_1.argument = '2'
        db.session.flush()
        assert current_access.get_action_cache('open::1') is None
        assert current_access.get_action_cache('open::2') is None
        permission_open_2 = dynamic_permission(
            ParameterizedActionNeed('open', '2'))
        assert permission_open_2.allows(identity_user_6)
        assert current_access.get_action_cache('open::2') == (set([
            Need(method='id', value=1),
            Need(method='id', value=2),
            Need(method='id', value=5),
            Need(method='id', value=6)
        ]), set([]))
        # open action cache should remain as before
        assert current_access.get_action_cache('open') == (set([
            Need(method='id', value=1),
            Need(method='id', value=2),
            Need(method='id', value=5)
        ]), set([]))
예제 #10
0
def app(request, search_class):
    """Flask application fixture.
    
    Note that RECORDS_REST_ENDPOINTS is used during application creation to
    create blueprints on the fly, hence once you have this fixture in a test,
    it's too late to customize the configuration variable. You can however
    customize it using parameterized tests:
    .. code-block:: python
    @pytest.mark.parametrize('app', [dict(
        endpoint=dict(
            search_class='conftest:TestSearch',
        )
    def test_mytest(app, db, es):
        # ...
    This will parameterize the default 'recid' endpoint in
    RECORDS_REST_ENDPOINTS.
    Alternatively:
    .. code-block:: python
    @pytest.mark.parametrize('app', [dict(
        records_rest_endpoints=dict(
            recid=dict(
                search_class='conftest:TestSearch',
            )
        )
    def test_mytest(app, db, es):
        # ...
    This will fully parameterize RECORDS_REST_ENDPOINTS.
    """
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    from records import config
    app.config.update(
        ACCOUNTS_JWT_ENABLE=False,
        INDEXER_DEFAULT_DOC_TYPE='record-v1.0.0',
        INDEXER_DEFAULT_INDEX=search_class.Meta.index,
        RECORDS_REST_ENDPOINTS=copy.deepcopy(config.RECORDS_REST_ENDPOINTS),
        RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_SEARCH_INDEX=search_class.Meta.index,
        SERVER_NAME='localhost:5000',
        CELERY_ALWAYS_EAGER=True,
        CELERY_RESULT_BACKEND='cache',
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )
    app.config['RECORDS_REST_ENDPOINTS']['recid']['search_class'] = \
        search_class

    app.config['RECORDS_REST_ENDPOINTS']['recid']['create_permission_factory_imp'] = \
        user_id_1_perm

    app.config['RECORDS_REST_ENDPOINTS']['recid']['record_class'] = \
        SchemaEnforcingRecord

    app.secret_key = 'changeme'

    # Parameterize application.
    if hasattr(request, 'param'):
        if 'endpoint' in request.param:
            app.config['RECORDS_REST_ENDPOINTS']['recid'].update(
                request.param['endpoint'])
        if 'records_rest_endpoints' in request.param:
            original_endpoint = app.config['RECORDS_REST_ENDPOINTS']['recid']
            del app.config['RECORDS_REST_ENDPOINTS']['recid']
            for new_endpoint_prefix, new_endpoint_value in \
                request.param['records_rest_endpoints'].items():
                new_endpoint = dict(original_endpoint)
                new_endpoint.update(new_endpoint_value)
                app.config['RECORDS_REST_ENDPOINTS'][new_endpoint_prefix] = \
                    new_endpoint

    app.url_map.converters['pid'] = PIDConverter

    InvenioDB(app)
    InvenioREST(app)
    InvenioRecords(app)
    schemas = InvenioJSONSchemas(app)
    indexer = InvenioIndexer(app)
    InvenioPIDStore(app)
    search = InvenioSearch(app)
    search.register_mappings(search_class.Meta.index, 'records.mappings')
    schemas._state.register_schemas_dir(
        os.path.join(os.path.dirname(__file__), 'records', 'jsonschemas'))
    InvenioRecordsREST(app)
    InvenioAccess(app)
    explicit_acls = InvenioExplicitAcls(app)
    principal = Principal(app)

    login_manager = LoginManager()
    login_manager.init_app(app)
    login_manager.login_view = 'login'

    @login_manager.user_loader
    def basic_user_loader(user_id):
        user_obj = User.query.get(int(user_id))
        return user_obj

    app.register_blueprint(create_blueprint_from_app(app))

    @app.route('/test/login/<int:id>', methods=['GET', 'POST'])
    def test_login(id):
        print("test: logging user with id", id)
        response = make_response()
        user = User.query.get(id)
        login_user(user)
        set_identity(user)
        return response

    with app.app_context():
        yield app

    # Teardown instance path.
    shutil.rmtree(instance_path)
예제 #11
0
    CELERY_ALWAYS_EAGER=True,
    CELERY_CACHE_BACKEND='memory',
    CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
    CELERY_RESULT_BACKEND='cache',
    MAIL_SUPPRESS_SEND=True,
    SECRET_KEY='CHANGE_ME',
    SECURITY_PASSWORD_SALT='CHANGE_ME_ALSO',
    SQLALCHEMY_TRACK_MODIFICATIONS=False,
    WTF_CSRF_ENABLED=False,
)

Babel(app)
Mail(app)
InvenioDB(app)
InvenioAccounts(app)
InvenioAccess(app)
InvenioAssets(app)
InvenioI18N(app)
InvenioTheme(app)
admin_app = InvenioAdmin(app)
app.register_blueprint(accounts_blueprint)
app.register_blueprint(admin_blueprint)


@app.route('/')
def index():
    """Basic test view."""
    flash(
        Markup('Login with username <strong>[email protected]</strong> '
               'and password <strong>123456</strong>.'))
    return redirect('/admin/')
예제 #12
0
def app(request):
    """Flask application fixture."""
    # Set temporary instance path for sqlite
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)

    app.config.update(SQLALCHEMY_DATABASE_URI=os.environ.get(
        'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
                      TESTING=True,
                      SECRET_KEY='SECRET_KEY',
                      SQLALCHEMY_TRACK_MODIFICATIONS=False,
                      JSONSCHEMAS_ENDPOINT='/schema',
                      JSONSCHEMAS_HOST='ils.test.rero.ch',
                      RECORDS_UI_ENDPOINTS={
                          "doc": {
                              "pid_type":
                              "doc",
                              "route":
                              "/documents/<pid_value>",
                              "template":
                              "reroils_data/detailed_view_documents_items.html"
                          }
                      })

    InvenioDB(app)
    InvenioPIDStore(app)
    InvenioRecords(app)
    InvenioAccounts(app)
    REROILSDATA(app)
    InvenioAccess(app)
    InvenioJSONSchemas(app)
    InvenioRecordsUI(app)
    Menu(app)
    Babel(app)
    app.register_blueprint(item_blueprint)

    @app.route('/test/login')
    def login():
        from flask_security import login_user
        from flask import request as flask_request

        role = flask_request.args.get('role')
        if role:
            datastore.create_role(name=role)
            datastore.add_role_to_user(user, role)
        datastore.commit()
        login_user(user)
        return "Logged In"

    @app.route('/test/login')
    def logout():
        from flask_security import logout_user
        logout_user()
        return "Logged Out"

    from invenio_db import db as db_
    with app.app_context():
        if not database_exists(str(db_.engine.url)):
            create_database(str(db_.engine.url))
        db_.create_all()
        security = LocalProxy(lambda: app.extensions['security'])
        datastore = LocalProxy(lambda: security.datastore)
        user = datastore.create_user(email='*****@*****.**',
                                     active=True,
                                     password=hash_password('aafaf4as5fa'))
        yield app

        # Teardown instance path.
        db_.session.remove()
        db_.drop_all()
        shutil.rmtree(instance_path)
예제 #13
0
def test_invenio_access_permission_cache_system_roles_updates(app):
    """Testing ActionSystemRoles cache with inserts/updates/deletes."""
    # This test case is doing the same of user test case but using
    # system roles.
    cache = SimpleCache()
    InvenioAccess(app, cache=cache)
    with app.test_request_context():
        system_role_1 = SystemRoleNeed('system_role_1')
        system_role_2 = SystemRoleNeed('system_role_2')
        system_role_3 = SystemRoleNeed('system_role_3')
        system_role_4 = SystemRoleNeed('system_role_4')
        system_role_5 = SystemRoleNeed('system_role_5')
        system_role_6 = SystemRoleNeed('system_role_6')
        current_access.system_roles = {
            'system_role_1': system_role_1,
            'system_role_2': system_role_2,
            'system_role_3': system_role_3,
            'system_role_4': system_role_4,
            'system_role_5': system_role_5,
            'system_role_6': system_role_6,
        }

        # Creation of some data to test.
        db.session.add(
            ActionSystemRoles(action='open', role_name=system_role_1.value))
        db.session.add(
            ActionSystemRoles(action='write', role_name=system_role_4.value))

        db.session.flush()

        # Creation of identities to test.
        identity_fake_1 = FakeIdentity(system_role_1)
        identity_fake_2 = FakeIdentity(system_role_2)
        identity_fake_3 = FakeIdentity(system_role_3)
        identity_fake_4 = FakeIdentity(system_role_4)
        identity_fake_5 = FakeIdentity(system_role_5)
        identity_fake_6 = FakeIdentity(system_role_6)

        # Test if system_role_1 can open. In this case, the cache should store
        # only this object.
        permission_open = DynamicPermission(ActionNeed('open'))
        assert permission_open.allows(identity_fake_1)
        assert current_access.get_action_cache('open') == (set([system_role_1
                                                                ]), set([]))

        # Test if system_role_2 can write. In this case, the cache should
        # have this new object and the previous one (Open is allowed to
        # system_role_1)
        permission_write = DynamicPermission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_4)
        assert current_access.get_action_cache('write') == (set(
            [system_role_4]), set([]))
        assert current_access.get_action_cache('open') == (set([system_role_1
                                                                ]), set([]))

        # If we add a new system role to the action open, the open action in
        # cache should be removed but it should still containing the write
        # entry.
        db.session.add(
            ActionSystemRoles(action='open', role_name=system_role_2.value))
        db.session.flush()
        assert current_access.get_action_cache('open') is None
        permission_open = DynamicPermission(ActionNeed('open'))
        assert permission_open.allows(identity_fake_2)
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2]), set([]))
        assert current_access.get_action_cache('write') == (set(
            [system_role_4]), set([]))

        # Test if the new role is added to the action 'open'
        permission_write = DynamicPermission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_4)
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2]), set([]))
        assert current_access.get_action_cache('write') == (set(
            [system_role_4]), set([]))

        # If we update an action swapping a role, the cache containing the
        # action, should be removed.
        role_4_action_write = ActionSystemRoles.query.filter(
            ActionSystemRoles.action == 'write'
            and ActionSystemRoles.role_name == system_role_4.value).first()
        role_4_action_write.role_name = system_role_3.value
        db.session.flush()

        assert current_access.get_action_cache('write') is None
        assert current_access.get_action_cache('open') is not None
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2]), set([]))

        # Test if the system_role_3 can write now.
        permission_write = DynamicPermission(ActionNeed('write'))
        assert not permission_write.allows(identity_fake_4)
        permission_write = DynamicPermission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_3)
        assert current_access.get_action_cache('write') == (set(
            [system_role_3]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2]), set([]))

        # If we remove a role from an action, the cache should clear the
        # action item.
        cust_action_write = ActionSystemRoles.query.filter(
            ActionSystemRoles.action == 'write'
            and ActionSystemRoles.role_name == system_role_3).first()
        db.session.delete(cust_action_write)
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        # If no one is allowed to perform an action then everybody is allowed.
        permission_write = DynamicPermission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_3)
        assert current_access.get_action_cache('write') == (set([]), set([]))
        db.session.add(
            ActionSystemRoles(action='write', role_name=system_role_5.value))
        db.session.flush()
        permission_write = DynamicPermission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_5)
        permission_write = DynamicPermission(ActionNeed('write'))
        assert not permission_write.allows(identity_fake_3)
        assert current_access.get_action_cache('write') == (set(
            [system_role_5]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2]), set([]))

        # If you update the name of an existing action, the previous action
        # and the new action should be remove from cache.
        permission_write = DynamicPermission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_5)
        assert current_access.get_action_cache('write') == (set(
            [system_role_5]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2]), set([]))
        role_5_action_write = ActionSystemRoles.query.filter(
            ActionSystemRoles.action == 'write'
            and ActionSystemRoles.role_name == system_role_5.value).first()
        role_5_action_write.action = 'open'
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        assert current_access.get_action_cache('open') is None
        permission_open = DynamicPermission(ActionNeed('open'))
        assert permission_open.allows(identity_fake_1)
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2, system_role_5]), set([]))
        db.session.add(
            ActionSystemRoles(action='write', role_name=system_role_4.value))
        permission_write = DynamicPermission(ActionNeed('write'))
        assert not permission_write.allows(identity_fake_5)
        assert current_access.get_action_cache('write') == (set(
            [system_role_4]), set([]))

        db.session.add(
            ActionSystemRoles(action='open',
                              argument='1',
                              role_name=system_role_6.value))
        db.session.flush()
        permission_open_1 = DynamicPermission(
            ParameterizedActionNeed('open', '1'))
        assert not permission_open.allows(identity_fake_6)
        assert permission_open_1.allows(identity_fake_6)
        assert current_access.get_action_cache('open::1') == (set(
            [system_role_1, system_role_2, system_role_5,
             system_role_6]), set([]))
        user_6_action_open_1 = ActionSystemRoles.query.filter_by(
            action='open', argument='1',
            role_name=system_role_6.value).first()
        user_6_action_open_1.argument = '2'
        db.session.flush()
        assert current_access.get_action_cache('open::1') is None
        assert current_access.get_action_cache('open::2') is None
        permission_open_2 = DynamicPermission(
            ParameterizedActionNeed('open', '2'))
        assert permission_open_2.allows(identity_fake_6)
        assert current_access.get_action_cache('open::2') == (set(
            [system_role_1, system_role_2, system_role_5,
             system_role_6]), set([]))
        # open action cache should remain as before
        assert current_access.get_action_cache('open') == (set(
            [system_role_1, system_role_2, system_role_5]), set([]))
예제 #14
0
def test_invenio_access_argument_permission_for_users(app):
    """User can access to an action allowed/denied with argument 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_argument_dummy = User(email='*****@*****.**')

        db.session.add(superuser)
        db.session.add(user_can_all)
        db.session.add(user_can_argument_dummy)

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

        db.session.add(ActionUsers(action='argument1',
                                   user=user_can_all))
        db.session.add(ActionUsers(action='argument1',
                                   argument='other',
                                   user=user_can_all))
        db.session.add(ActionUsers(action='argument1',
                                   argument='dummy',
                                   user=user_can_argument_dummy))
        db.session.add(ActionUsers(action='argument2',
                                   argument='other',
                                   user=user_can_all))
        db.session.commit()

        permission_argument1 = DynamicPermission(ActionNeed('argument1'))
        permission_argument1_dummy = DynamicPermission(
            ParameterizedActionNeed('argument1', 'dummy'))
        permission_argument1_other = DynamicPermission(
            ParameterizedActionNeed('argument1', 'other'))
        permission_argument2 = DynamicPermission(ActionNeed('argument2'))
        permission_argument2_dummy = DynamicPermission(
            ParameterizedActionNeed('argument2', 'dummy'))
        permission_argument2_other = DynamicPermission(
            ParameterizedActionNeed('argument2', 'other'))

        identity_superuser = FakeIdentity(UserNeed(superuser.id))
        identity_all = FakeIdentity(UserNeed(user_can_all.id))
        identity_unknown = AnonymousIdentity()
        identity_argument_dummy = FakeIdentity(
            UserNeed(user_can_argument_dummy.id))

        # tests for super user
        assert permission_argument1.allows(identity_superuser)
        assert permission_argument1_dummy.allows(identity_superuser)
        assert permission_argument1_other.allows(identity_superuser)
        assert permission_argument2.allows(identity_superuser)
        assert permission_argument2_dummy.allows(identity_superuser)
        assert permission_argument2_other.allows(identity_superuser)

        # first tests for permissions with argument
        assert permission_argument1.allows(identity_all)
        assert permission_argument1_dummy.allows(identity_all)
        assert permission_argument1_other.allows(identity_all)

        assert not permission_argument1.allows(identity_argument_dummy)
        assert permission_argument1_dummy.allows(identity_argument_dummy)
        assert not permission_argument1_other.allows(identity_argument_dummy)

        assert not permission_argument1.allows(identity_unknown)
        assert not permission_argument1_dummy.allows(identity_unknown)
        assert not permission_argument1_other.allows(identity_unknown)

        # second tests for permissions with arguments
#        assert permission_argument2.allows(identity_all)
#        assert permission_argument2_dummy.allows(identity_all)
        assert permission_argument2_other.allows(identity_all)

#        assert permission_argument2.allows(identity_argument_dummy)
#        assert permission_argument2_dummy.allows(identity_argument_dummy)
        assert not permission_argument2_other.allows(identity_argument_dummy)

#        assert permission_argument2.allows(identity_unknown)
#        assert permission_argument2_dummy.allows(identity_unknown)
        assert not permission_argument2_other.allows(identity_unknown)
예제 #15
0
def app(request, accounts_rest_permission_factory):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask(__name__, instance_path=instance_path)
    InvenioAccess(app)
    InvenioAccounts(app)
    InvenioAccountsREST(app)
    InvenioOAuth2Server(app)
    InvenioOAuth2ServerREST(app)
    InvenioDB(app)
    Babel(app)
    Mail(app)
    Menu(app)
    Breadcrumbs(app)

    # this is done mainly for coverage so that tests are run with and without
    # userprofiles being loaded in the app
    if not hasattr(request, 'param') or \
            'with_profiles' not in request.param or \
            request.param['with_profiles']:
        # tests without invenio-userprofiles being installed at all
        try:
            from invenio_userprofiles import InvenioUserProfiles
            InvenioUserProfiles(app)
        except ImportError:
            pass

    read_role = accounts_rest_permission_factory['read_role']
    update_role = accounts_rest_permission_factory['update_role']
    delete_role = accounts_rest_permission_factory['delete_role']
    read_roles = accounts_rest_permission_factory['read_roles_list']
    create_role = accounts_rest_permission_factory['create_role']
    assign_role = accounts_rest_permission_factory['assign_role']
    unassign_role = accounts_rest_permission_factory['unassign_role']
    role_users = accounts_rest_permission_factory['read_role_users_list']
    user_roles = accounts_rest_permission_factory['read_user_roles_list']
    read_user_prop = accounts_rest_permission_factory['read_user_properties']
    mod_user_prop = accounts_rest_permission_factory['update_user_properties']
    read_users = accounts_rest_permission_factory['read_users_list']

    app.config.update(
        ACCOUNTS_REST_READ_ROLE_PERMISSION_FACTORY=read_role,
        ACCOUNTS_REST_UPDATE_ROLE_PERMISSION_FACTORY=update_role,
        ACCOUNTS_REST_DELETE_ROLE_PERMISSION_FACTORY=delete_role,
        ACCOUNTS_REST_READ_ROLES_LIST_PERMISSION_FACTORY=read_roles,
        ACCOUNTS_REST_CREATE_ROLE_PERMISSION_FACTORY=create_role,
        ACCOUNTS_REST_ASSIGN_ROLE_PERMISSION_FACTORY=assign_role,
        ACCOUNTS_REST_UNASSIGN_ROLE_PERMISSION_FACTORY=unassign_role,
        ACCOUNTS_REST_READ_ROLE_USERS_LIST_PERMISSION_FACTORY=role_users,
        ACCOUNTS_REST_READ_USER_ROLES_LIST_PERMISSION_FACTORY=user_roles,
        ACCOUNTS_REST_READ_USER_PROPERTIES_PERMISSION_FACTORY=read_user_prop,
        ACCOUNTS_REST_UPDATE_USER_PROPERTIES_PERMISSION_FACTORY=mod_user_prop,
        ACCOUNTS_REST_READ_USERS_LIST_PERMISSION_FACTORY=read_users,
        OAUTH2SERVER_CLIENT_ID_SALT_LEN=40,
        OAUTH2SERVER_CLIENT_SECRET_SALT_LEN=60,
        OAUTH2SERVER_TOKEN_PERSONAL_SALT_LEN=60,
        SECRET_KEY='changeme',
        TESTING=True,
        SERVER_NAME='localhost',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SECURITY_SEND_PASSWORD_CHANGE_EMAIL=False)

    from invenio_oauth2server.views.server import blueprint

    with app.app_context():
        db_.create_all()
    yield app
    with app.app_context():
        db_.drop_all()
예제 #16
0
def app(mapping, schema):
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)

    app.config.update(
        JSONSCHEMAS_HOST="example.com",
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='127.0.0.1:5000',
        INVENIO_INSTANCE_PATH=instance_path,
        DEBUG=True,
        # in tests, api is not on /api but directly in the root
        PIDSTORE_RECID_FIELD='pid',
        FLASK_TAXONOMIES_URL_PREFIX='/2.0/taxonomies/',
        RECORDS_REST_ENDPOINTS=RECORDS_REST_ENDPOINTS,
        CELERY_BROKER_URL='amqp://*****:*****@localhost:5672//',
        CELERY_TASK_ALWAYS_EAGER=True,
        CELERY_RESULT_BACKEND='cache',
        CELERY_CACHE_BACKEND='memory',
        CELERY_TASK_EAGER_PROPAGATES=True)

    app.secret_key = 'changeme'
    print(os.environ.get("INVENIO_INSTANCE_PATH"))

    InvenioDB(app)
    OarepoTaxonomies(app)
    OARepoReferences(app)
    InvenioAccounts(app)
    InvenioAccess(app)
    Principal(app)
    InvenioJSONSchemas(app)
    InvenioSearch(app)
    OARepoMappingIncludesExt(app)
    InvenioRecords(app)
    InvenioRecordsREST(app)
    InvenioCelery(app)
    OARepoValidate(app)

    # Celery
    print(app.config["CELERY_BROKER_URL"])

    login_manager = LoginManager()
    login_manager.init_app(app)
    login_manager.login_view = 'login'

    @login_manager.user_loader
    def basic_user_loader(user_id):
        user_obj = User.query.get(int(user_id))
        return user_obj

    # app.register_blueprint(create_blueprint_from_app(app))

    @app.route('/test/login/<int:id>', methods=['GET', 'POST'])
    def test_login(id):
        print("test: logging user with id", id)
        response = make_response()
        user = User.query.get(id)
        login_user(user)
        set_identity(user)
        return response

    app.extensions['invenio-search'].mappings["test"] = mapping
    app.extensions["invenio-jsonschemas"].schemas["test"] = schema

    app_loaded.send(app, app=app)

    with app.app_context():
        # app.register_blueprint(taxonomies_blueprint)
        yield app

    shutil.rmtree(instance_path)
예제 #17
0
def test_init(base_app):
    """Test extension initialization."""
    app = base_app
    ext = InvenioAccess(app)
    assert 'invenio-access' in app.extensions
예제 #18
0
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

FlaskCLI(app)
Babel(app)
Mail(app)
Menu(app)
InvenioDB(app)
InvenioAccounts(app)
app.register_blueprint(blueprint)

InvenioAdmin(app, permission_factory=lambda x: x,
             view_class_factory=lambda x: x)

access = InvenioAccess(app)

action_read = ActionNeed('read')
access.register_action(action_read)
action_read_permission = DynamicPermission(action_read)


@app.route('/action_read')
@action_read_permission.require()
def action_read():
    pass


action_upload_content = ActionNeed('add_content')
access.register_action(action_upload_content)
upload_content_permission = DynamicPermission(action_upload_content)
예제 #19
0
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

FlaskCLI(app)
Babel(app)
Mail(app)
Menu(app)
InvenioDB(app)
InvenioAccounts(app)
app.register_blueprint(blueprint)

InvenioAdmin(app,
             permission_factory=lambda x: x,
             view_class_factory=lambda x: x)

access = InvenioAccess(app)

action_read = ActionNeed('read')
access.register_action(action_read)
action_read_permission = DynamicPermission(action_read)


@app.route('/action_read')
@action_read_permission.require()
def action_read():
    pass


action_upload_content = ActionNeed('add_content')
access.register_action(action_upload_content)
upload_content_permission = DynamicPermission(action_upload_content)
예제 #20
0
from invenio_access import InvenioAccess
from invenio_access.permissions import DynamicPermission

# Create Flask application
app = Flask(__name__)
app.secret_key = "ExampleApp"
FlaskCLI(app)
Babel(app)
Mail(app)
Menu(app)
InvenioDB(app)
InvenioAccounts(app)
app.register_blueprint(blueprint)

access = InvenioAccess(app)

action_open = ActionNeed("open")
access.register_action(action_open)

action_read = ActionNeed("read")
access.register_action(action_read)


@app.route("/")
def index():
    """Basic test view."""
    identity = g.identity
    actions = {}
    for action in access.actions:
        actions[action.value] = DynamicPermission(action).allows(identity)
예제 #21
0
def app():
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)

    app.config.update(
        JSONSCHEMAS_HOST="nusl.cz",
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='127.0.0.1:5000',
        INVENIO_INSTANCE_PATH=instance_path,
        DEBUG=True,
        # SQLALCHEMY_ECHO=True,
        SUPPORTED_LANGUAGES=["cs", "en"],
        # SQLALCHEMY_DATABASE_URI='postgresql+psycopg2://oarepo:oarepo@localhost/oarepo',
        OAREPO_COMMUNITIES_ENDPOINTS=[],
        OAREPO_OAI_PROVIDERS={
            "nusl": {
                "description":
                "NUŠL",
                "synchronizers": [{
                    "name":
                    "marcxml",
                    "oai_endpoint":
                    "http://invenio.nusl.cz/oai2d/",
                    "set":
                    "global",
                    "metadata_prefix":
                    "marcxml",
                    "unhandled_paths": [
                        '/leader', '/005', '/008', '020__/q', '/0248_',
                        '/246__', '/340__', '/500__', '/502__/a', '/502__/b',
                        '/502__/d', '/502__/g', '/506__', '/6530_', '/6557_',
                        '/655_7', "/656_7/2", '/8560_', '/85642/z', '/8564_',
                        '/909CO/p', '999c1', '/999C2', 'FFT_0'
                    ],
                    "default_endpoint":
                    "common",
                }]
            },
        },
        # RECORDS_REST_ENDPOINTS=RECORDS_REST_ENDPOINTS,
        PIDSTORE_RECID_FIELD='pid')

    app.secret_key = 'changeme'

    InvenioDB(app)
    InvenioAccounts(app)
    InvenioAccess(app)
    Principal(app)
    InvenioJSONSchemas(app)
    InvenioSearch(app)
    InvenioIndexer(app)
    InvenioRecords(app)
    InvenioRecordsREST(app)
    InvenioPIDStore(app)
    app.url_map.converters['pid'] = PIDConverter
    app.url_map.converters['commpid'] = CommunityPIDConverter
    OarepoTaxonomies(app)
    OArepoOAIClient(app)
    OARepoValidate(app)
    RecordsDraft(app)
    # NRCommon(app)
    NRTheses(app)
    NRNresults(app)
    NREvents(app)

    app_loaded.send(app, app=app)

    with app.app_context():
        yield app

    shutil.rmtree(instance_path)
예제 #22
0
def app():
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)

    app.config.update(
        JSONSCHEMAS_HOST="nusl.cz",
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='127.0.0.1:5000',
        INVENIO_INSTANCE_PATH=instance_path,
        DEBUG=True,
        # in tests, api is not on /api but directly in the root
        PIDSTORE_RECID_FIELD='pid',
        FLASK_TAXONOMIES_URL_PREFIX='/2.0/taxonomies/',
        # RECORDS_REST_ENDPOINTS=RECORDS_REST_ENDPOINTS,
        CELERY_BROKER_URL='amqp://*****:*****@localhost:5672//',
        CELERY_TASK_ALWAYS_EAGER=True,
        CELERY_RESULT_BACKEND='cache',
        CELERY_CACHE_BACKEND='memory',
        CELERY_TASK_EAGER_PROPAGATES=True,
        SUPPORTED_LANGUAGES=["cs", "en"],
        OAREPO_COMMUNITIES_ENDPOINTS=[],
        ELASTICSEARCH_DEFAULT_LANGUAGE_TEMPLATE={
            "type": "text",
            "fields": {
                "keywords": {
                    "type": "keyword"
                }
            }
        })

    app.secret_key = 'changeme'
    print(os.environ.get("INVENIO_INSTANCE_PATH"))

    InvenioDB(app)
    OarepoTaxonomies(app)
    OARepoReferences(app)
    InvenioAccounts(app)
    InvenioAccess(app)
    Principal(app)
    InvenioJSONSchemas(app)
    InvenioSearch(app)
    InvenioIndexer(app)
    OARepoMappingIncludesExt(app)
    InvenioRecords(app)
    InvenioRecordsREST(app)
    InvenioCelery(app)
    NRNresults(app)
    InvenioPIDStore(app)
    OARepoValidate(app)
    OARepoCommunities(app)
    # Invenio Records Draft initialization
    RecordsDraft(app)
    app.url_map.converters['pid'] = PIDConverter
    app.url_map.converters['commpid'] = CommunityPIDConverter

    # Celery
    print(app.config["CELERY_BROKER_URL"])

    login_manager = LoginManager()
    login_manager.init_app(app)
    login_manager.login_view = 'login'

    @login_manager.user_loader
    def basic_user_loader(user_id):
        user_obj = User.query.get(int(user_id))
        return user_obj

    app.register_blueprint(create_blueprint_from_app(app))

    @app.route('/test/login/<int:id>', methods=['GET', 'POST'])
    def test_login(id):
        print("test: logging user with id", id)
        response = make_response()
        user = User.query.get(id)
        login_user(user)
        set_identity(user)
        return response

    # app.extensions['invenio-search'].mappings["test"] = mapping
    # app.extensions["invenio-jsonschemas"].schemas["test"] = schema

    app_loaded.send(app, app=app)

    with app.app_context():
        # app.register_blueprint(taxonomies_blueprint)
        print(app.url_map)
        yield app

    shutil.rmtree(instance_path)
예제 #23
0
def access_app(app):
    """Init InvenioAccess app and return a request context."""
    InvenioAccess(app)
    with app.test_request_context():
        yield app
예제 #24
0
def test_intenio_access_cache_performance(app, dynamic_permission):
    """Performance test simulating 1000 users."""
    InvenioAccess(app, cache=None)
    with app.test_request_context():
        # CDS has (2015-11-19) 74 actions with 414 possible arguments with
        # 49259 users and 307 roles. In this test we are going to divide
        # into 50 and use the next prime number.
        users_number = 991
        actions_users_number = 11
        actions_roles_number = 7

        roles = []
        actions = []
        for i in range(actions_roles_number):
            role = Role(name='role{0}'.format(i))
            roles.append(role)
            db.session.add(role)
            db.session.flush()

            action_role = ActionRoles(action='action{0}'.format(
                str(i % actions_roles_number)),
                                      role=role)
            actions.append(action_role)
            db.session.add(action_role)
            db.session.flush()

        users = []
        for i in range(users_number):
            user = User(email='invenio{0}@inveniosoftware.org'.format(str(i)),
                        roles=[roles[i % actions_roles_number]])
            users.append(user)
            db.session.add(user)
            db.session.flush()

            action_user = ActionUsers(action='action{0}'.format(
                str((i % actions_users_number) + actions_roles_number)),
                                      user=user)
            actions.append(action_user)
            db.session.add(action_user)
            db.session.flush()

        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 = dynamic_permission(
                    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 = dynamic_permission(
                    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 = dynamic_permission(
                    ActionNeed('action{0}'.format(
                        (i + 1) % actions_roles_number)))
                assert not permission_not_allowed_role.allows(identity)

        app.extensions['invenio-access'].cache = None
        start_time_wo_cache = time.time()
        test_permissions()
        end_time_wo_cache = time.time()
        time_wo_cache = end_time_wo_cache - start_time_wo_cache

        app.extensions['invenio-access'].cache = SimpleCache()
        start_time_w_cache = time.time()
        test_permissions()
        end_time_w_cache = time.time()
        time_w_cache = end_time_w_cache - start_time_w_cache

        assert time_wo_cache / time_w_cache > 10
예제 #25
0
def test_permission(app):
    """Test permission control to records."""
    app.config.update(
        WTF_CSRF_ENABLED=False,
        SECRET_KEY='CHANGEME',
        SECURITY_PASSWORD_SALT='CHANGEME',
        # conftest switches off permission checking, so re-enable it for this
        # app.
        RECORDS_UI_DEFAULT_PERMISSION_FACTORY='invenio_records.permissions'
        ':read_permission_factory')
    Menu(app)
    InvenioRecordsUI(app)
    accounts = InvenioAccounts(app)
    app.register_blueprint(accounts_blueprint)
    InvenioAccess(app)
    setup_record_fixture(app)

    # Create admin
    with app.app_context():
        admin = accounts.datastore.create_user(
            email='*****@*****.**',
            password=encrypt_password('123456'),
            active=True,
        )
        reader = accounts.datastore.create_user(
            email='*****@*****.**',
            password=encrypt_password('123456'),
            active=True,
        )

        # Get record 1
        r = Resolver(pid_type='recid',
                     object_type='rec',
                     getter=Record.get_record)
        dummy_pid, record = r.resolve('1')

        # Setup permissions for record 1 (grant 'admin', deny 'reader')
        db.session.add(
            ActionUsers(action=records_read_all.value,
                        argument=str(record.id),
                        user=admin))
        db.session.add(
            ActionUsers(action=records_read_all.value,
                        argument=str(record.id),
                        user=reader,
                        exclude=True))
        db.session.commit()

    with app.test_request_context():
        login_url = url_for('security.login')
        record_url = url_for('invenio_records_ui.recid', pid_value='1')

    # Access record 1 as admin
    with app.test_client() as client:
        res = client.get(record_url)
        assert res.status_code == 302
        res = client.post(login_url,
                          data={
                              'email': '*****@*****.**',
                              'password': '******'
                          })
        assert res.status_code == 302
        res = client.get(record_url)
        res.status_code == 200

    # Access record 1 as reader
    with app.test_client() as client:
        res = client.post(login_url,
                          data={
                              'email': '*****@*****.**',
                              'password': '******'
                          })
        assert res.status_code == 302
        res = client.get(record_url)
        res.status_code == 403
예제 #26
0
def test_invenio_access_permission_cache_roles_updates(app,
                                                       dynamic_permission):
    """Testing ActionRoles cache with inserts/updates/deletes."""
    # This test case is doing the same of user test case but using roles.
    cache = SimpleCache()
    InvenioAccess(app, cache=cache)
    with app.test_request_context():
        # Creation of some data to test.
        role_1 = Role(name='role_1')
        role_2 = Role(name='role_2')
        role_3 = Role(name='role_3')
        role_4 = Role(name='role_4')
        role_5 = Role(name='role_5')
        role_6 = Role(name='role_6')

        db.session.add(role_1)
        db.session.add(role_2)
        db.session.add(role_3)
        db.session.add(role_4)
        db.session.add(role_5)
        db.session.add(role_6)

        db.session.add(ActionRoles(action='open', role=role_1))
        db.session.add(ActionRoles(action='write', role=role_4))

        db.session.flush()

        # Creation of identities to test.
        identity_fake_role_1 = FakeIdentity(RoleNeed(role_1.name))
        identity_fake_role_2 = FakeIdentity(RoleNeed(role_2.name))
        identity_fake_role_3 = FakeIdentity(RoleNeed(role_3.name))
        identity_fake_role_4 = FakeIdentity(RoleNeed(role_4.name))
        identity_fake_role_5 = FakeIdentity(RoleNeed(role_5.name))
        identity_fake_role_6 = FakeIdentity(RoleNeed(role_6.name))

        # Test if role 1 can open. In this case, the cache should store only
        # this object.
        permission_open = dynamic_permission(ActionNeed('open'))
        assert permission_open.allows(identity_fake_role_1)
        assert current_access.get_action_cache('open') == (set(
            [Need(method='role', value=role_1.name)]), set([]))

        # Test if role 4 can write. In this case, the cache should have this
        # new object and the previous one (Open is allowed to role_1)
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_role_4)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_4.name)]), set([]))
        assert current_access.get_action_cache('open') == (set(
            [Need(method='role', value=role_1.name)]), set([]))

        # If we add a new role to the action open, the open action in cache
        # should be removed but it should still containing the write entry.
        db.session.add(ActionRoles(action='open', role=role_2))
        db.session.flush()
        assert current_access.get_action_cache('open') is None
        permission_open = dynamic_permission(ActionNeed('open'))
        assert permission_open.allows(identity_fake_role_2)
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name)
        ]), set([]))
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_4.name)]), set([]))

        # Test if the new role is added to the action 'open'
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_role_4)
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name)
        ]), set([]))
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_4.name)]), set([]))

        # If we update an action swapping a role, the cache containing the
        # action, should be removed.
        role_4_action_write = ActionRoles.query.filter(
            ActionRoles.action == 'write'
            and ActionRoles.role == role_4).first()
        role_4_action_write.role = role_3
        db.session.flush()

        assert current_access.get_action_cache('write') is None
        assert current_access.get_action_cache('open') is not None
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name)
        ]), set([]))

        # Test if the role_3 can write now.
        permission_write = dynamic_permission(ActionNeed('write'))
        assert not permission_write.allows(identity_fake_role_4)
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_role_3)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_3.name)]), set([]))
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name)
        ]), set([]))

        # If we remove a role from an action, the cache should clear the
        # action item.
        role_3_action_write = ActionRoles.query.filter(
            ActionRoles.action == 'write'
            and ActionRoles.role == role_3).first()
        db.session.delete(role_3_action_write)
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        # If no one is allowed to perform an action then everybody is allowed.
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_role_3)
        assert current_access.get_action_cache('write') == (set([]), set([]))
        db.session.add(ActionRoles(action='write', role=role_5))
        db.session.flush()
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_role_5)
        permission_write = dynamic_permission(ActionNeed('write'))
        assert not permission_write.allows(identity_fake_role_3)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_5.name)]), set([]))
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name)
        ]), set([]))

        # If you update the name of an existing action, the previous action
        # and the new action should be remove from cache.
        permission_write = dynamic_permission(ActionNeed('write'))
        assert permission_write.allows(identity_fake_role_5)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_5.name)]), set([]))
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name)
        ]), set([]))
        role_5_action_write = ActionRoles.query.filter(
            ActionRoles.action == 'write'
            and ActionRoles.role == role_5).first()
        role_5_action_write.action = 'open'
        db.session.flush()
        assert current_access.get_action_cache('write') is None
        assert current_access.get_action_cache('open') is None
        permission_open = dynamic_permission(ActionNeed('open'))
        assert permission_open.allows(identity_fake_role_1)
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name),
            Need(method='role', value=role_5.name)
        ]), set([]))
        db.session.add(ActionRoles(action='write', role=role_4))
        permission_write = dynamic_permission(ActionNeed('write'))
        assert not permission_write.allows(identity_fake_role_5)
        assert current_access.get_action_cache('write') == (set(
            [Need(method='role', value=role_4.name)]), set([]))

        db.session.add(ActionRoles(action='open', argument='1', role=role_6))
        db.session.flush()
        permission_open_1 = dynamic_permission(
            ParameterizedActionNeed('open', '1'))
        assert not permission_open.allows(identity_fake_role_6)
        assert permission_open_1.allows(identity_fake_role_6)
        assert current_access.get_action_cache('open::1') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name),
            Need(method='role', value=role_5.name),
            Need(method='role', value=role_6.name)
        ]), set([]))
        user_6_action_open_1 = ActionRoles.query.filter_by(
            action='open', argument='1', role_id=role_6.id).first()
        user_6_action_open_1.argument = '2'
        db.session.flush()
        assert current_access.get_action_cache('open::1') is None
        assert current_access.get_action_cache('open::2') is None
        permission_open_2 = dynamic_permission(
            ParameterizedActionNeed('open', '2'))
        assert permission_open_2.allows(identity_fake_role_6)
        assert current_access.get_action_cache('open::2') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name),
            Need(method='role', value=role_5.name),
            Need(method='role', value=role_6.name)
        ]), set([]))
        # open action cache should remain as before
        assert current_access.get_action_cache('open') == (set([
            Need(method='role', value=role_1.name),
            Need(method='role', value=role_2.name),
            Need(method='role', value=role_5.name)
        ]), set([]))
예제 #27
0
def base_app(app_config):
    """Flask application fixture."""
    instance_path = os.path.join(sys.prefix, 'var', 'test-instance')

    # empty the instance path
    if os.path.exists(instance_path):
        shutil.rmtree(instance_path)
    os.makedirs(instance_path)

    os.environ['INVENIO_INSTANCE_PATH'] = instance_path

    app_ = Flask('oarepo-s3-testapp', instance_path=instance_path)
    app_.config.update(
        TESTING=True,
        JSON_AS_ASCII=True,
        FILES_REST_PERMISSION_FACTORY=allow_all,
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI',
            'sqlite:///:memory:'),
        SERVER_NAME='localhost:5000',
        SECURITY_PASSWORD_SALT='TEST_SECURITY_PASSWORD_SALT',
        SECRET_KEY='TEST_SECRET_KEY',
        INVENIO_INSTANCE_PATH=instance_path,
        # SEARCH_INDEX_PREFIX='records-',
        RECORDS_REST_ENDPOINTS={},
        SEARCH_INDEX_PREFIX='test-',
        FILES_REST_DEFAULT_STORAGE_CLASS='S',
        CELERY_ALWAYS_EAGER=True,
        JSONSCHEMAS_HOST='localhost:5000',
        SEARCH_ELASTIC_HOSTS=os.environ.get('SEARCH_ELASTIC_HOSTS', None)
    )
    app_.config.update(**app_config)
    app.test_client_class = JsonClient

    Principal(app_)

    login_manager = LoginManager()
    login_manager.init_app(app_)
    login_manager.login_view = 'login'

    @login_manager.user_loader
    def basic_user_loader(user_id):
        user_obj = User.query.get(int(user_id))
        return user_obj

    @app_.route('/test/login/<int:id>', methods=['GET', 'POST'])
    def test_login(id):
        print("test: logging user with id", id)
        response = make_response()
        user = User.query.get(id)
        print('User is', user)
        login_user(user)
        set_identity(user)
        return response

    @app_.route('/test/logout', methods=['GET', 'POST'])
    def test_logout():
        print("test: logging out")
        response = make_response()
        logout_user()

        # Remove session keys set by Flask-Principal
        for key in ('identity.name', 'identity.auth_type'):
            session.pop(key, None)

        # Tell Flask-Principal the user is anonymous
        identity_changed.send(current_app._get_current_object(),
                              identity=AnonymousIdentity())

        return response

    from oarepo_s3 import config  # noqa

    InvenioAccess(app_)
    InvenioDB(app_)
    InvenioFilesREST(app_)
    InvenioS3(app_)
    InvenioIndexer(app_)
    InvenioSearch(app_)
    RecordsDraft(app_)
    OARepoS3(app_)

    return app_