def setUp(self):
        from invenio_accounts.models import User
        from invenio_oauth2server.registry import scopes
        from invenio_oauth2server.models import Token, Scope

        # Setup variables:
        self.called = dict()

        # Setup test scopes
        with self.app.app_context():
            scopes.register(Scope("test:testscope", group="Test", help_text="Test scope"))

        # Setup API resources
        class Test1Resource(Resource):
            # NOTE: Method decorators are applied in reverse order
            method_decorators = [require_oauth_scopes("test:testscope"), require_api_auth()]

            def get(self):
                assert request.oauth.access_token
                return "success", 200

            def post(self):
                assert request.oauth.access_token
                return "success", 200

            @require_header("Content-Type", "application/json")
            def put(self):
                return "success", 200

        class Test2Resource(Resource):
            @require_api_auth()
            @require_oauth_scopes("test:testscope")
            def get(self):
                assert request.oauth.access_token
                return "success", 200

            @require_api_auth()
            @require_oauth_scopes("test:testscope")
            def post(self):
                assert request.oauth.access_token
                return "success", 200

            @require_header("Content-Type", "text/html")
            def put(self):
                return "success", 200

        # Register API resources
        api = self.app.extensions["restful"]
        api.add_resource(Test1Resource, "/api/test1/decoratorstestcase/")
        api.add_resource(Test2Resource, "/api/test2/decoratorstestcase/")

        # Create a user
        self.user = User(email="*****@*****.**", nickname="tester")
        self.user.password = "******"
        db.session.add(self.user)
        db.session.commit()

        # Create tokens
        self.token = Token.create_personal("test-", self.user.id, scopes=["test:testscope"], is_internal=True)
        self.token_noscope = Token.create_personal("test-", self.user.id, scopes=[], is_internal=True)
Example #2
0
def user():
    """Create circulation admin user."""
    from werkzeug.local import LocalProxy
    from flask_security.utils import encrypt_password

    from invenio_db import db
    from invenio_oauth2server.models import Token

    _datastore = LocalProxy(lambda: app.extensions['security'].datastore)
    kwargs = dict(
        email='*****@*****.**',
        password='******',
        active=True
    )
    kwargs['password'] = encrypt_password(kwargs['password'])
    user = _datastore.create_user(**kwargs)

    Token.create_personal(
        'test-personal-{0}'.format(user.id),
        user.id,
        scopes=['webhooks:event'],
        is_internal=True,
    ).access_token

    db.session.commit()
    def test_token_scopes(self):
        from invenio_oauth2server.models import Client, Token
        from invenio_oauth2server.errors import ScopeDoesNotExists

        c = Client(
            client_id='dev2',
            client_secret='dev2',
            name='dev2',
            description='',
            is_confidential=False,
            user=self.objects[0],
            _redirect_uris='',
            _default_scopes=""
        )
        t = Token(
            client=c,
            user=self.objects[0],
            token_type='bearer',
            access_token='dev_access',
            refresh_token='dev_refresh',
            expires=None,
            is_personal=False,
            is_internal=False,
            _scopes='',
        )
        t.scopes = ['test:scope1', 'test:scope2', 'test:scope2']
        self.create_objects([c, t])
        self.assertEqual(t.scopes, ['test:scope1', 'test:scope2'])
        self.assertRaises(ScopeDoesNotExists,
                          t.__setattr__, 'scopes', ['invalid'])
        self.assertEqual(t.get_visible_scopes(),
                         ['test:scope1'])
        self.delete_objects([c])
Example #4
0
def _create_new_record_version(app):
    """Create a new version of a record existing before the upgrade."""
    from invenio_accounts.models import User
    from flask_security import url_for_security
    from flask_security.utils import hash_password
    from flask import url_for
    from invenio_oauth2server.models import Token
    user = User.query.filter(User.email=='*****@*****.**').one()
    user.password = hash_password('123')
    token = Token.create_personal(
        'other_token', user.id,
        scopes=[]
    )
    headers = [
        ('Authorization', 'Bearer {}'.format(token.access_token)),
        ('Content-type', 'application/json')
    ]
    db.session.commit()
    with app.test_request_context():
        login_url = url_for_security('login')
    with app.test_client() as client:
        res = client.post(login_url, data={
            'email': '*****@*****.**', 'password': '******'
        })
        assert res.status_code == 302
        url = url_for('b2share_records_rest.b2rec_list',
                      version_of='1033083fedf4408fb5611f23527a926d')
        res = client.post(url, headers=headers)
        assert res.status_code == 201
Example #5
0
    def init_account(self):
        """Setup a new GitHub account."""
        ghuser = self.api.me()
        # Setup local access tokens to be used by the webhooks
        hook_token = ProviderToken.create_personal(
            'github-webhook',
            self.user_id,
            scopes=['webhooks:event'],
            is_internal=True,
        )
        # Initial structure of extra data
        self.account.extra_data = dict(
            id=ghuser.id,
            login=ghuser.login,
            name=ghuser.name,
            tokens=dict(
                webhook=hook_token.id,
            ),
            repos=dict(),
            last_sync=iso_utcnow(),
        )
        db.session.add(self.account)

        # Sync data from GitHub, but don't check repository hooks yet.
        self.sync(hooks=False)
    def setUp(self):
        """Set up some dummy data and a resource."""
        from invenio_accounts.models import User
        from invenio_oauth2server.models import Token

        self.data = range(25)

        # setup test api resources

        class TestDataResource(Resource):

            method_decorators = [require_api_auth()]

            @require_header("Content-Type", "application/json")
            def get(self):
                import json
                from flask import make_response
                from invenio_ext.restful.errors import InvalidPageError
                from invenio_ext.restful import pagination

                # Test to see that the exceptions are raised correctly
                # In restful.py it is not needed because the error_hanler
                # takes care of exceptions
                response = None
                try:
                    # test data
                    testdata = range(25)
                    endpoint = request.endpoint
                    args = request.args
                    page = int(args.get("page", 1))
                    per_page = int(args.get("per_page", 10))
                    p = pagination.RestfulPagination(page=page, per_page=per_page, total_count=len(testdata))
                    data_to_return = p.slice(testdata)
                    kwargs = {}
                    kwargs["endpoint"] = endpoint
                    kwargs["args"] = request.args
                    link_header = p.link_header(**kwargs)
                    response = make_response(json.dumps(data_to_return))
                    response.headers[link_header[0]] = link_header[1]
                    response.headers["Content-Type"] = request.headers["Content-Type"]
                except InvalidPageError as e:
                    exception = {}
                    exception["message"] = e.error_msg
                    exception["type"] = "{0}".format(type(e))
                    response = make_response(json.dumps(exception))
                return response

        # Register API resources
        api = self.app.extensions["restful"]
        api.add_resource(TestDataResource, "/api/testdata/")

        # Create a user
        self.user = User(email="*****@*****.**", nickname="tester")
        self.user.password = "******"
        db.session.add(self.user)
        db.session.commit()

        # create token
        self.token = Token.create_personal("test-", self.user.id, scopes=[], is_internal=True)
Example #7
0
def test_deposit(app, test_communities, login_user, authentication):
    """Test record submission with classic login and access token."""
    with app.app_context():
        allowed_user = create_user('allowed')

        scopes = current_oauth2server.scope_choices()
        allowed_token = Token.create_personal(
            'allowed_token', allowed_user.id,
            scopes=[s[0] for s in scopes]
        )
        # application authentication token header
        allowed_headers = [('Authorization',
                            'Bearer {}'.format(allowed_token.access_token))]

        other_user = create_user('other')
        other_token = Token.create_personal(
            'other_token', other_user.id,
            scopes=[s[0] for s in scopes]
        )
        # application authentication token header
        other_headers = [('Authorization',
                          'Bearer {}'.format(other_token.access_token))]

        community_name = 'MyTestCommunity1'
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_admin_token = Token.create_personal(
            'com_admin_token', com_admin.id,
            scopes=[s[0] for s in scopes]
        )
        # application authentication token header
        com_admin_headers = [('Authorization',
                              'Bearer {}'.format(com_admin_token.access_token))]

        test_records_data = [generate_record_data(community=community_name)
                             for idx in range(1,3)]

        db.session.commit()

    if authentication == 'user/password':
        subtest_deposit(app, test_communities, allowed_user, other_user,
                        com_admin, [], [], [], login_user, test_records_data)
    else:
        subtest_deposit(app, test_communities, allowed_user, other_user,
                        com_admin, allowed_headers, other_headers,
                        com_admin_headers, lambda u, c: 42, test_records_data)
Example #8
0
 def create_oauth_token(self, user_id, scopes, is_internal=True):
     """Create an OAuth personal access_token."""
     # Create a personal access token as well.
     from invenio_oauth2server.models import Token
     self.accesstoken[user_id] = Token.create_personal(
         'test-personal-%s' % user_id,
         user_id,
         scopes=scopes,
         is_internal=is_internal
     ).access_token
Example #9
0
def access_token_no_scope(app, tester_id):
    """Fixture that create an access token without scope."""
    token = Token.create_personal(
        'test-personal-{0}'.format(tester_id),
        tester_id,
        scopes=[''],
        is_internal=True,
    ).access_token
    db.session.commit()
    return token
Example #10
0
def access_token(app, db, tester_id):
    """Fixture that create an access token."""
    token = Token.create_personal(
        'test-personal-{0}'.format(tester_id),
        tester_id,
        scopes=['webhooks:event'],
        is_internal=True,
    ).access_token
    db.session.commit()
    return token
Example #11
0
def deposit_token(app, db, tester_id):
    """Fixture that create an access token."""
    token = Token.create_personal(
        'deposit-personal-{0}'.format(tester_id),
        tester_id,
        scopes=['deposit:write', 'deposit:actions'],
        is_internal=True,
    ).access_token
    db.session.commit()
    return token
Example #12
0
def provider_fixture(app):
    """Fixture that contains test data for provider tests."""
    from invenio_oauth2server.proxies import current_oauth2server
    # Mock the oauth client calls to prevent them from going online.
    oauth_client = create_oauth_client(app, 'oauth2test')
    oauth_client.http_request = MagicMock(
        side_effect=patch_request(app)
    )
    datastore = app.extensions['security'].datastore
    with app.test_request_context():
        with db.session.begin_nested():
            current_oauth2server.register_scope(Scope('test:scope'))

            user1 = datastore.create_user(
                email='*****@*****.**', password='******',
                active=True,
            )
            datastore.create_user(
                email='*****@*****.**', password='******',
                active=True
            )

            c1 = Client(client_id='dev',
                        client_secret='dev',
                        name='dev',
                        description='',
                        is_confidential=False,
                        user=user1,
                        _redirect_uris=url_for(
                            'oauth2test.authorized', _external=True
                        ),
                        _default_scopes='test:scope'
                        )
            c2 = Client(client_id='confidential',
                        client_secret='confidential',
                        name='confidential',
                        description='',
                        is_confidential=True,
                        user=user1,
                        _redirect_uris=url_for(
                            'oauth2test.authorized', _external=True
                        ),
                        _default_scopes='test:scope'
                        )
            db.session.add(c1)
            db.session.add(c2)
        personal_token = Token.create_personal('test-personal',
                                               user1.id,
                                               scopes=[],
                                               is_internal=True)
        db.session.commit()

        app.user1_id = user1.id
        app.personal_token = personal_token.access_token
    return app
Example #13
0
    def post(self, **kwargs):
        token_name = request.get_json().get('token_name')
        if not token_name:
            abort(400)

        scopes = current_oauth2server.scope_choices()
        token = Token.create_personal(
            token_name, current_user.get_id(), scopes=[s[0] for s in scopes]
        )
        db.session.commit()
        return token_to_json_serializer(token, show_access_token=True, code=201)
Example #14
0
 def _create(cls, model_class, *args, **kwargs):
     if "role" in kwargs:
         user = UserFactory(role=kwargs["role"])
     else:
         user = UserFactory()
     user = User.query.filter(User.email == user.email).one_or_none()
     token = Token.create_personal(fake.name(),
                                   user.id,
                                   scopes={},
                                   is_internal=True)
     return token
def access_token(app, tester_id):
    """Fixture that create an access token."""
    with app.app_context():
        token = Token.create_personal(
            'test-personal-{0}'.format(tester_id),
            tester_id,
            scopes=['webhooks:event'],
            is_internal=True,
        ).access_token
        db.session.commit()
        return token
Example #16
0
def provider_fixture(app):
    """Fixture that contains test data for provider tests."""
    from invenio_oauth2server.proxies import current_oauth2server
    # Mock the oauth client calls to prevent them from going online.
    oauth_client = create_oauth_client(app, 'oauth2test')
    oauth_client.http_request = MagicMock(
        side_effect=patch_request(app)
    )
    datastore = app.extensions['security'].datastore
    with app.test_request_context():
        with db.session.begin_nested():
            current_oauth2server.register_scope(Scope('test:scope'))

            app.user1 = datastore.create_user(
                email='*****@*****.**', password='******',
                active=True,
            )
            app.user2 = datastore.create_user(
                email='*****@*****.**', password='******',
                active=True
            )

            app.c1 = Client(client_id='dev',
                            client_secret='dev',
                            name='dev',
                            description='',
                            is_confidential=False,
                            user=app.user1,
                            _redirect_uris=url_for(
                                'oauth2test.authorized', _external=True
                            ),
                            _default_scopes='test:scope'
                            )

            app.c2 = Client(client_id='confidential',
                            client_secret='confidential',
                            name='confidential',
                            description='',
                            is_confidential=True,
                            user=app.user1,
                            _redirect_uris=url_for(
                                'oauth2test.authorized', _external=True
                            ),
                            _default_scopes='test:scope'
                            )
            db.session.add(app.c1)
            db.session.add(app.c2)
        app.personal_token = Token.create_personal('test-personal',
                                                   app.user1.id,
                                                   scopes=[],
                                                   is_internal=True)

    return app
Example #17
0
def access_token(api_app, db, users):
    """Fixture that create an access token."""
    with db.session.begin_nested():
        tester_id = User.query.get(users[0]).id
        token = Token.create_personal(
            'test-personal-{0}'.format(tester_id),
            tester_id,
            scopes=['webhooks:event'],
            is_internal=True,
        ).access_token
    db.session.commit()
    return token
Example #18
0
def init_provider_tokens(user_id):
    """Create local access token.

    It is used to authenticate GitHub webhook as well as the upload using
    the API.
    """
    webhook_token = ProviderToken.create_personal(
        'github-webhook',
        user_id,
        scopes=['webhooks:event'],
        is_internal=True,
    )

    internal_token = ProviderToken.create_personal(
        'github-upload',
        user_id,
        scopes=['deposit:write', 'deposit:actions'],
        is_internal=True,
    )

    return webhook_token, internal_token
Example #19
0
def init_provider_tokens(user_id):
    """Create local access token.

    It is used to authenticate GitHub webhook as well as the upload using
    the API.
    """
    webhook_token = ProviderToken.create_personal(
        'github-webhook',
        user_id,
        scopes=['webhooks:event'],
        is_internal=True,
    )

    internal_token = ProviderToken.create_personal(
        'github-upload',
        user_id,
        scopes=['deposit:write', 'deposit:actions'],
        is_internal=True,
    )

    return webhook_token, internal_token
def test_token_scopes(models_fixture):
    app = models_fixture
    with app.app_context():
        client = Client(
            client_id='dev2',
            client_secret='dev2',
            name='dev2',
            description='',
            is_confidential=False,
            user=app.test_user,
            _redirect_uris='',
            _default_scopes=""
        )
        token = Token(
            client=client,
            user=app.test_user,
            token_type='bearer',
            access_token='dev_access',
            refresh_token='dev_refresh',
            expires=None,
            is_personal=False,
            is_internal=False,
            _scopes='',
        )
        token.scopes = ['test:scope1', 'test:scope2', 'test:scope2']
        with db.session.begin_nested():
            db.session.add(client)
            db.session.add(token)

        assert set(token.scopes) == set(
            ['test:scope1', 'test:scope2'])
        with pytest.raises(ScopeDoesNotExists):
            token.scopes = ['invalid']
        assert token.get_visible_scopes() == ['test:scope1']

        with db.session.begin_nested():
            db.session.delete(client)
Example #21
0
def test_token_scopes(models_fixture):
    app = models_fixture
    with app.app_context():
        client = Client(
            client_id='dev2',
            client_secret='dev2',
            name='dev2',
            description='',
            is_confidential=False,
            user=app.test_user(),
            _redirect_uris='',
            _default_scopes=""
        )
        token = Token(
            client=client,
            user=app.test_user(),
            token_type='bearer',
            access_token='dev_access',
            refresh_token='dev_refresh',
            expires=None,
            is_personal=False,
            is_internal=False,
            _scopes='',
        )
        token.scopes = ['test:scope1', 'test:scope2', 'test:scope2']
        with db.session.begin_nested():
            db.session.add(client)
            db.session.add(token)

        assert set(token.scopes) == set(
            ['test:scope1', 'test:scope2'])
        with pytest.raises(ScopeDoesNotExists):
            token.scopes = ['invalid']
        assert token.get_visible_scopes() == ['test:scope1']

        with db.session.begin_nested():
            db.session.delete(client)
Example #22
0
def rat_generate_token(app, db, oauth2_client, users):
    """Create token."""
    with db.session.begin_nested():
        token_ = Token(
            client_id=oauth2_client,
            user_id=users[0]['id'],
            access_token='rat_token',
            expires=datetime.utcnow() + timedelta(hours=10),
            is_personal=False,
            is_internal=True,
            _scopes=tokens_generate_scope.id,
        )
        db.session.add(token_)
    db.session.commit()
    return token_
Example #23
0
def write_token_user_2(app, client, users):
    """Create token."""
    with db.session.begin_nested():
        token_ = Token(
            client=client,
            user_id=users[1]["id"],
            access_token="dev_access_2",
            refresh_token="dev_refresh_2",
            expires=datetime.datetime.now() + datetime.timedelta(hours=10),
            is_personal=False,
            is_internal=True,
            _scopes=write_scope.id,
        )
        db.session.add(token_)
    db.session.commit()
    return token_
def access_token(app, db):
    _datastore = LocalProxy(lambda: app.extensions['security'].datastore)
    kwargs = dict(email='*****@*****.**', password='******',
                  active=True)
    kwargs['password'] = encrypt_password(kwargs['password'])
    user = _datastore.create_user(**kwargs)

    db.session.commit()
    token = Token.create_personal(
        'test-personal-{0}'.format(user.id),
        user.id,
        scopes=['webhooks:event'],
        is_internal=True,
    ).access_token
    db.session.commit()

    yield token
Example #25
0
def token_new():
    """Create new token."""
    data, errors = TokenSchema().load(request.get_json())

    if errors:
        return jsonify({"errors": errors}), 400

    t = Token.create_personal(data.get("name"),
                              current_user.get_id(),
                              scopes=data.get("scopes"))
    db.session.commit()
    return jsonify({
        "t_id": t.id,
        "name": t.client.name,
        "scopes": t.scopes,
        "access_token": t.access_token
    }), 200
def user(db, app):
    """File system location."""
    user = User(email='*****@*****.**', active=True)
    db.session.add(user)

    role = Role(name='*****@*****.**')
    role.users.append(user)
    db.session.add(role)

    db.session.commit()

    token = Token.create_personal('test', user.id)
    db.session.commit()

    app.config['API_TOKEN'] = token.access_token

    yield user
Example #27
0
def create_personal(name,
                    user_id,
                    scopes=None,
                    is_internal=False,
                    access_token=None):
    """Create a personal access token.

    A token that is bound to a specific user and which doesn't expire, i.e.
    similar to the concept of an API key.

    :param name: Client name.
    :param user_id: User ID.
    :param scopes: The list of permitted scopes. (Default: ``None``)
    :param is_internal: If ``True`` it's a internal access token.
            (Default: ``False``)
    :param access_token: personalized access_token.
    :returns: A new access token.
    """
    with db.session.begin_nested():
        scopes = " ".join(scopes) if scopes else ""

        client = Client(name=name,
                        user_id=user_id,
                        is_internal=True,
                        is_confidential=False,
                        _default_scopes=scopes)
        client.gen_salt()

        if not access_token:
            access_token = gen_salt(
                current_app.config.get('OAUTH2SERVER_TOKEN_PERSONAL_SALT_LEN'))
        token = Token(
            client_id=client.client_id,
            user_id=user_id,
            access_token=access_token,
            expires=None,
            _scopes=scopes,
            is_personal=True,
            is_internal=is_internal,
        )

        db.session.add(client)
        db.session.add(token)

    return token
Example #28
0
def access_token(app, db):
    _datastore = LocalProxy(lambda: app.extensions['security'].datastore)
    kwargs = dict(email='*****@*****.**',
                  password='******',
                  active=True)
    kwargs['password'] = encrypt_password(kwargs['password'])
    user = _datastore.create_user(**kwargs)

    db.session.commit()
    token = Token.create_personal(
        'test-personal-{0}'.format(user.id),
        user.id,
        scopes=['webhooks:event'],
        is_internal=True,
    ).access_token
    db.session.commit()

    yield token
Example #29
0
def users(app, db, roles_data, users_data, create_roles):
    """Create test users."""
    ds = app.extensions['invenio-accounts'].datastore
    result = {}

    with app.app_context():
        with db.session.begin_nested():

            for user_key, user_data in iteritems(users_data):
                user_data['password'] = hash_password(user_data['password'])
                user = ds.create_user(**user_data)
                result[user_key] = user

            roles = Role.query.filter(
                Role.id.in_(role['id'] for role in create_roles[:5])).all()
            result['user1'].roles.extend(roles)

            db.session.add(
                ActionUsers.allow(
                    superuser_access,
                    user=result['admin'],
                ))

            for user in result.values():
                scopes = current_oauth2server.scope_choices()
                db.session.add(user)

                user.allowed_token = Token.create_personal(
                    name='allowed_token',
                    user_id=user.id,
                    scopes=[s[0] for s in scopes]).access_token

            user_ref = namedtuple('UserRef', 'id, allowed_token, data')

            result_user = {
                name: user_ref(
                    id=user.id,
                    data=users_data[name],
                    allowed_token=user.allowed_token,
                )
                for name, user in six.iteritems(result)
            }
        db.session.commit()
    return result_user
Example #30
0
def extra_token(app, db, oauth2_client, users):
    """Create token."""
    with db.session.begin_nested():
        token_ = Token(client_id=oauth2_client,
                       user_id=users[0]['id'],
                       access_token='dev_access_2',
                       refresh_token='dev_refresh_2',
                       expires=datetime.utcnow() + timedelta(hours=10),
                       is_personal=False,
                       is_internal=True,
                       _scopes=' '.join(
                           [extra_formats_scope.id, write_scope.id]))
        db.session.add(token_)
    db.session.commit()
    return dict(token=token_,
                auth_header=[
                    ('Authorization',
                     'Bearer {0}'.format(token_.access_token)),
                ])
Example #31
0
    def _write_token(user):
        """Return json headers with write oauth token for given user."""
        client_ = Client.query.filter_by(
            user_id=user.id
        ).first()

        if not client_:
            client_ = Client(
                client_id=user.id,
                client_secret='client_secret_{}'.format(user.id),
                name='client_test_{}'.format(user.id),
                description='',
                is_confidential=False,
                user_id=user.id,
                _redirect_uris='',
                _default_scopes='',
            )
            db.session.add(client_)

        token_ = Token.query.filter_by(
            user_id=user.id
        ).first()

        if not token_:
            token_ = Token(
                client_id=client_.client_id,
                user_id=user.id,
                access_token='dev_access_{}'.format(user.id),
                refresh_token='dev_refresh_{}'.format(user.id),
                expires=datetime.utcnow() + timedelta(hours=10),
                is_personal=False,
                is_internal=True,
                _scopes=write_scope.id,
            )
            db.session.add(token_)
        db.session.commit()

        return bearer_auth(dict(
            token=token_,
            auth_header=[
                ('Authorization', 'Bearer {0}'.format(token_.access_token)),
            ]
        ))
Example #32
0
    def account_search(user, expected_code):
        headers = [('Content-Type', 'application/json'),
                   ('Accept', 'application/json')]
        with app.app_context():
            url = url_for('invenio_accounts_rest.users_list')
            if user:
                scopes = current_oauth2server.scope_choices()
                allowed_token = Token.create_personal(
                    'allowed_token', user.id, scopes=[s[0] for s in scopes])
                # application authentication token header
                headers.append(
                    ('Authorization',
                     'Bearer {}'.format(allowed_token.access_token)))

        with app.test_client() as client:
            if user is not None:
                login_user(user, client)
            res = client.get(url, headers=headers)
            assert res.status_code == expected_code
    def account_search(user, expected_code):
        headers = [('Content-Type', 'application/json'),
                   ('Accept', 'application/json')]
        with app.app_context():
            url = url_for('invenio_accounts_rest.users_list')
            if user:
                scopes = current_oauth2server.scope_choices()
                allowed_token = Token.create_personal(
                    'allowed_token', user.id,
                    scopes=[s[0] for s in scopes]
                )
                # application authentication token header
                headers.append(('Authorization',
                                'Bearer {}'.format(allowed_token.access_token)))

        with app.test_client() as client:
            if user is not None:
                login_user(user, client)
            res = client.get(url, headers=headers)
            assert res.status_code == expected_code
Example #34
0
def create_user_token(client_name, user, access_token):
    """Create a token for the given user."""
    # Create token for user
    with db.session.begin_nested():
        client = Client(name=client_name,
                        user_id=user.id,
                        is_internal=True,
                        is_confidential=False,
                        _default_scopes='')
        client.gen_salt()
        token = Token(client_id=client.client_id,
                      user_id=user.id,
                      access_token=access_token,
                      expires=None,
                      is_personal=True,
                      is_internal=True,
                      _scopes='')
        db.session.add(client)
        db.session.add(token)
    return token
def token_new():
    """Create new token."""
    data, errors = TokenSchema().load(request.get_json())

    if errors:
        return jsonify({"errors": errors}), 400

    t = Token.create_personal(
        data.get("name"),
        current_user.get_id(),
        scopes=data.get("scopes")
    )
    db.session.commit()
    return jsonify(
        {
            "t_id": t.id,
            "name": t.client.name,
            "scopes": t.scopes,
            "access_token": t.access_token
        }), 200
Example #36
0
def init_authentication_token():
    with db.session.begin_nested():
        client = Client(name='admin',
                        user_id=1,
                        is_internal=True,
                        is_confidential=False,
                        _default_scopes="")
        client.gen_salt()

        token = Token(
            client_id=client.client_id,
            user_id=1,
            access_token=current_app.config["AUTHENTICATION_TOKEN"],
            expires=None,
            _scopes="",
            is_personal=True,
            is_internal=True,
        )

        db.session.add(client)
        db.session.add(token)
    db.session.commit()
Example #37
0
    def init_account(self):
        """Setup a new GitHub account."""
        ghuser = self.api.me()
        # Setup local access tokens to be used by the webhooks
        hook_token = ProviderToken.create_personal(
            'github-webhook',
            self.user_id,
            scopes=['webhooks:event'],
            is_internal=True,
        )
        # Initial structure of extra data
        self.account.extra_data = dict(
            id=ghuser.id,
            login=ghuser.login,
            name=ghuser.name,
            tokens=dict(webhook=hook_token.id, ),
            repos=dict(),
            last_sync=iso_utcnow(),
        )
        db.session.add(self.account)

        # Sync data from GitHub, but don't check repository hooks yet.
        self.sync(hooks=False)
Example #38
0
    def setUp(self):
        """Set up some dummy data and a resource."""
        from invenio_accounts.models import User
        from invenio_oauth2server.models import Token

        self.data = range(25)

        # setup test api resources

        class TestDataResource(Resource):

            method_decorators = [require_api_auth()]

            @require_header('Content-Type', 'application/json')
            def get(self):
                import json
                from flask import make_response
                from invenio_ext.restful.errors import (InvalidPageError)
                from invenio_ext.restful import pagination
                # Test to see that the exceptions are raised correctly
                # In restful.py it is not needed because the error_hanler
                # takes care of exceptions
                response = None
                try:
                    # test data
                    testdata = range(25)
                    endpoint = request.endpoint
                    args = request.args
                    page = int(args.get('page', 1))
                    per_page = int(args.get('per_page', 10))
                    p = pagination.RestfulPagination(page=page,
                                                     per_page=per_page,
                                                     total_count=len(testdata))
                    data_to_return = p.slice(testdata)
                    kwargs = {}
                    kwargs['endpoint'] = endpoint
                    kwargs['args'] = request.args
                    link_header = p.link_header(**kwargs)
                    response = make_response(json.dumps(data_to_return))
                    response.headers[link_header[0]] = link_header[1]
                    response.headers['Content-Type'] = request.headers[
                        'Content-Type']
                except InvalidPageError as e:
                    exception = {}
                    exception['message'] = e.error_msg
                    exception['type'] = "{0}".format(type(e))
                    response = make_response(json.dumps(exception))
                return response

        # Register API resources
        api = self.app.extensions['restful']
        api.add_resource(TestDataResource, '/api/testdata/')

        # Create a user
        self.user = User(email='*****@*****.**', nickname='tester')
        self.user.password = "******"
        db.session.add(self.user)
        db.session.commit()

        # create token
        self.token = Token.create_personal('test-',
                                           self.user.id,
                                           scopes=[],
                                           is_internal=True)
Example #39
0
def test_patron_info(app, client, patron_martigny, librarian_martigny):
    """Test patron info."""

    # All scopes
    scopes = [
        'fullname', 'birthdate', 'institution', 'expiration_date',
        'patron_type', 'patron_types'
    ]

    # create a oauth client liked to the librarian account
    oauth_client = Client(client_id='dev',
                          client_secret='dev',
                          name='Test name',
                          description='Test description',
                          is_confidential=False,
                          user=librarian_martigny.user,
                          website='http://foo.org',
                          _redirect_uris='')

    # token with all scopes
    token = Token(client=oauth_client,
                  user=patron_martigny.user,
                  token_type='bearer',
                  access_token='test_access_1',
                  expires=None,
                  is_personal=False,
                  is_internal=False,
                  _scopes=' '.join(scopes))

    # token without scope
    no_scope_token = Token(client=oauth_client,
                           user=patron_martigny.user,
                           token_type='bearer',
                           access_token='test_access_2',
                           expires=None,
                           is_personal=False,
                           is_internal=False)

    db.session.add(oauth_client)
    db.session.add(token)
    db.session.commit()

    # denied with a wrong token
    res = client.get(url_for('api_patrons.info', access_token='wrong'))
    assert res.status_code == 401

    # denied without token
    res = client.get(url_for('api_patrons.info'))
    assert res.status_code == 401

    # minimal information without scope
    res = client.get(
        url_for('api_patrons.info', access_token=no_scope_token.access_token))
    assert res.status_code == 200
    assert res.json == {'barcode': patron_martigny['patron']['barcode'].pop()}

    # full information with all scopes
    res = client.get(
        url_for('api_patrons.info', access_token=token.access_token))
    assert res.status_code == 200
    assert res.json == {
        'barcode':
        '4098124352',
        'birthdate':
        '1947-06-07',
        'fullname':
        'Roduit, Louis',
        'patron_types': [{
            'expiration_date': '2023-10-07T00:00:00',
            'institution': 'org1',
            'patron_type': 'patron-code'
        }]
    }
Example #40
0
def resource_fixture(app):
    """Fixture that contains the test data for models tests."""
    from flask import request
    from invenio_oauth2server.proxies import current_oauth2server

    # Setup API resources
    class Test1Resource(MethodView):
        # NOTE: Method decorators are applied in reverse order
        decorators = [
            require_oauth_scopes('test:testscope'),
            require_api_auth(),
        ]

        def get(self):
            assert request.oauth.access_token
            return "success", 200

        def post(self):
            assert request.oauth.access_token
            return "success", 200

    class Test2Resource(MethodView):

        @require_api_auth()
        @require_oauth_scopes('test:testscope')
        def get(self):
            assert request.oauth.access_token
            return "success", 200

        @require_api_auth()
        @require_oauth_scopes('test:testscope')
        def post(self):
            assert request.oauth.access_token
            return "success", 200

    # Register API resources
    app.add_url_rule(
        '/api/test1/decoratorstestcase/',
        view_func=Test1Resource.as_view('test1resource'),
    )
    app.add_url_rule(
        '/api/test2/decoratorstestcase/',
        view_func=Test2Resource.as_view('test2resource'),
    )

    datastore = app.extensions['security'].datastore
    with app.app_context():
        # Register a test scope
        current_oauth2server.register_scope(Scope(
            'test:testscope',
            group='Test',
            help_text='Test scope'
        ))
        with db.session.begin_nested():
            app.user = datastore.create_user(
                email='*****@*****.**', password='******',
                active=True,
            )

        # Create tokens
        app.token = Token.create_personal(
            'test-', app.user.id, scopes=['test:testscope'], is_internal=True)
        app.token_noscope = Token.create_personal(
            'test-', app.user.id, scopes=[], is_internal=True)

    with app.test_request_context():
        app.url_for_test1resource = url_for('test1resource')
        app.url_for_test2resource = url_for('test2resource')
        app.url_for_test1resource_token = url_for(
            'test1resource', access_token=app.token.access_token
        )
        app.url_for_test2resource_token = url_for(
            'test2resource', access_token=app.token.access_token
        )
        app.url_for_test1resource_token_noscope = url_for(
            'test1resource', access_token=app.token_noscope.access_token
        )
        app.url_for_test2resource_token_noscope = url_for(
            'test2resource', access_token=app.token_noscope.access_token
        )

    return app
Example #41
0
def provider_fixture(app):
    """Fixture that contains test data for provider tests."""
    from invenio_oauth2server.proxies import current_oauth2server
    # Mock the oauth client calls to prevent them from going online.
    oauth_client = create_oauth_client(app, 'oauth2test')
    oauth_client.http_request = MagicMock(side_effect=patch_request(app))
    datastore = app.extensions['security'].datastore
    with app.test_request_context():
        with db.session.begin_nested():
            current_oauth2server.register_scope(Scope('test:scope'))

            user1 = datastore.create_user(
                email='*****@*****.**',
                password='******',
                active=True,
            )
            datastore.create_user(email='*****@*****.**',
                                  password='******',
                                  active=True)
            user3 = datastore.create_user(email='*****@*****.**',
                                          password='******',
                                          active=False)

            c1 = Client(client_id='dev',
                        client_secret='dev',
                        name='dev',
                        description='',
                        is_confidential=False,
                        user=user1,
                        _redirect_uris=url_for('oauth2test.authorized',
                                               _external=True),
                        _default_scopes='test:scope')
            c2 = Client(client_id='confidential',
                        client_secret='confidential',
                        name='confidential',
                        description='',
                        is_confidential=True,
                        user=user1,
                        _redirect_uris=url_for('oauth2test.authorized',
                                               _external=True),
                        _default_scopes='test:scope')
            # Same as 'c2' but user belonging to a user that's inactive
            c3 = Client(client_id='confidential-user-inactive',
                        client_secret='confidential-user-inactive',
                        name='confidential-user-inactive',
                        description='',
                        is_confidential=True,
                        user=user3,
                        _redirect_uris=url_for('oauth2test.authorized',
                                               _external=True),
                        _default_scopes='test:scope')
            c4 = Client(client_id='confidential-email',
                        client_secret='confidential-email',
                        name='confidential-email',
                        description='',
                        is_confidential=True,
                        user=user1,
                        _redirect_uris=url_for('oauth2test.authorized',
                                               _external=True),
                        _default_scopes='email')
            db.session.add(c1)
            db.session.add(c2)
            db.session.add(c3)
            db.session.add(c4)
        personal_token = Token.create_personal('test-personal',
                                               user1.id,
                                               scopes=[],
                                               is_internal=True)

        personal_token3 = Token.create_personal('test-personal',
                                                user3.id,
                                                scopes=[],
                                                is_internal=True)
        db.session.commit()

        app.user1_id = user1.id
        app.user3_id = user3.id
        app.personal_token = personal_token.access_token
        app.personal_token3 = personal_token3.access_token
    return app
Example #42
0
    def setUp(self):
        super(ProviderTestCase, self).setUp()
        # Set environment variable DEBUG to true, to allow testing without
        # SSL in oauthlib.
        if self.app.config.get('CFG_SITE_SECURE_URL').startswith('http://'):
            self.os_debug = os.environ.get('OAUTHLIB_INSECURE_TRANSPORT', '')
            os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = 'true'

        from invenio_accounts.models import User
        from invenio_oauth2server.models import Client, Scope
        from invenio_oauth2server.registry import scopes as scopes_registry

        self.assets_patcher = patch(
            'webassets.ext.jinja2.AssetsExtension._render_assets')
        _render_assets = self.assets_patcher.start()
        _render_assets.return_value = '/ping'

        # Register a test scope
        scopes_registry.register(Scope('test:scope'))

        self.base_url = self.app.config.get('CFG_SITE_SECURE_URL')

        # Create needed objects
        u = User(email='*****@*****.**', nickname='tester')
        u.password = "******"

        u2 = User(email='*****@*****.**', nickname='tester2')
        u2.password = "******"

        db.session.add(u)
        db.session.add(u2)

        c1 = Client(client_id='dev',
                    client_secret='dev',
                    name='dev',
                    description='',
                    is_confidential=False,
                    user=u,
                    _redirect_uris='%s/oauth2test/authorized' % self.base_url,
                    _default_scopes="test:scope")

        c2 = Client(client_id='confidential',
                    client_secret='confidential',
                    name='confidential',
                    description='',
                    is_confidential=True,
                    user=u,
                    _redirect_uris='%s/oauth2test/authorized' % self.base_url,
                    _default_scopes="test:scope")

        db.session.add(c1)
        db.session.add(c2)

        db.session.commit()

        self.objects = [u, u2, c1, c2]

        # Create a personal access token as well.
        from invenio_oauth2server.models import Token
        self.personal_token = Token.create_personal('test-personal',
                                                    1,
                                                    scopes=[],
                                                    is_internal=True)
Example #43
0
    def setUp(self):
        from flask_restful import Resource, fields, marshal
        from invenio_accounts.models import User
        from invenio_oauth2server.models import Token

        class TagRepresenation(object):

            """A representation of a tag.

            This class will be only used to return a tag as JSON.
            """

            marshaling_fields = dict(
                id=fields.Integer,
                name=fields.String,
                id_user=fields.Integer
            )

            def __init__(self, retrieved_tag):
                """Initialization.

                Declared the attributes to marshal with a tag.
                :param retrieved_tag: a tag from the database
                """
                # get fields from the given tag
                self.id = retrieved_tag.id
                self.name = retrieved_tag.name
                self.id_user = retrieved_tag.id_user

            def marshal(self):
                """Marshal the Tag."""
                return marshal(self, self.marshaling_fields)

        class TestTagsResource(Resource):

            method_decorators = [
                require_api_auth()
            ]

            @require_header('Content-Type', 'application/json')
            def get(self):
                import json
                from flask import make_response
                from invenio_ext.restful.errors import(
                    RestfulError, InvalidPageError
                )
                from invenio_ext.restful import pagination

                response = None
                try:
                    endpoint = request.endpoint
                    args = request.args
                    page = int(args.get('page', 1))
                    per_page = int(args.get('per_page', 2))
                    # check values arguments and raise exceptions if any errors
                    if per_page < 0:
                        raise RestfulError(
                            error_msg="Invalid per_page: {}".format(per_page),
                            status_code=400
                        )
                    if page < 0:
                        raise InvalidPageError(
                            error_msg="Invalid page: {}".format(page),
                            status_code=400
                        )

                    # need to sort by id
                    # also assuming only one user so no need to filter
                    # user's id
                    tags_q = WtgTAGPaginationMokup()
                    p = pagination.RestfulSQLAlchemyPagination(
                        query=tags_q, page=page, per_page=per_page
                    )
                    if page > p.pages:
                        raise InvalidPageError(
                            error_msg="Invalid page: {}".format(page),
                            status_code=400
                        )
                    tags_to_return = map(
                        lambda x: TagRepresenation(x).marshal(),
                        p.items
                    )

                    kwargs = {}
                    kwargs['endpoint'] = endpoint
                    kwargs['args'] = request.args
                    link_header = p.link_header(**kwargs)
                    response = make_response(json.dumps(tags_to_return))
                    response.headers[link_header[0]] = link_header[1]
                    response.headers[
                        'Content-Type'] = request.headers['Content-Type']
                except (RestfulError, InvalidPageError) as e:
                    exception = {}
                    exception['message'] = e.error_msg
                    exception['type'] = "{0}".format(type(e))
                    response = make_response(json.dumps(exception))
                return response

        # Register API resources
        api = self.app.extensions['restful']
        api.add_resource(
            TestTagsResource,
            '/api/testtags/'
        )

        # Create a user
        self.user = User(
            email='*****@*****.**', nickname='tester'
        )
        self.user.password = "******"
        db.session.add(self.user)
        db.session.commit()

        # create token
        self.token = Token.create_personal(
            'test-', self.user.id, scopes=[], is_internal=True)
Example #44
0
def test_file_download_statistics(app, test_community, test_users,
                                  test_records, login_user):
    """Test checking a record's DOI using CLI commands."""
    with app.app_context():

        def url_for(*args, **kwargs):
            """Generate url using flask.url_for and the current app ctx."""
            with app.app_context():
                return flask_url_for(*args, **kwargs)

        # create user that will create the record and the files
        scopes = current_oauth2server.scope_choices()

        allowed_user = create_user('allowed')

        scopes = current_oauth2server.scope_choices()
        allowed_token = Token.create_personal('allowed_token',
                                              allowed_user.id,
                                              scopes=[s[0] for s in scopes])
        # application authentication token header
        allowed_headers = [('Authorization',
                            'Bearer {}'.format(allowed_token.access_token))]

        community_name = 'MyTestCommunity1'
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin2', roles=[community.admin_role])
        com_admin_token = Token.create_personal('com_admin_token',
                                                com_admin.id,
                                                scopes=[s[0] for s in scopes])
        # application authentication token header
        com_admin_headers = [
            ('Authorization',
             'Bearer {}'.format(com_admin_token.access_token)),
            ('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) '
             'AppleWebKit/537.36 (KHTML, like Gecko)'
             'Chrome/45.0.2454.101 Safari/537.36')
        ]
        publish_headers = [('Content-Type', 'application/json-patch+json'),
                           ('Accept', 'application/json')] + com_admin_headers
        submit_headers = [('Content-Type', 'application/json-patch+json'),
                          ('Accept', 'application/json')] + allowed_headers
        stats_headers = [('Content-Type', 'application/json')]

        test_records_data = [
            generate_record_data(community=test_community.name)
            for idx in range(1, 3)
        ]

        for record_data in test_records_data:
            with app.test_client() as client:
                login_user(allowed_user, client)

                record_list_url = (lambda **kwargs: url_for(
                    'b2share_records_rest.b2rec_list', **kwargs))

                headers = [('Content-Type', 'application/json'),
                           ('Accept', 'application/json')] + allowed_headers
                draft_create_res = client.post(record_list_url(),
                                               data=json.dumps(record_data),
                                               headers=headers)
                assert draft_create_res.status_code == 201
                draft_create_data = json.loads(
                    draft_create_res.get_data(as_text=True))

                uploaded_files = {
                    'myfile1.html': b'contents1',
                    'myfile2.html': b'contents2'
                }

                for file_key, file_content in uploaded_files.items():
                    # Test file upload
                    headers = [('Accept', '*/*'),
                               ('Content-Type', 'text/html; charset=utf-8')
                               ] + allowed_headers
                    object_url = '{0}/{1}'.format(
                        draft_create_data['links']['files'], file_key)
                    file_put_res = client.put(
                        object_url,
                        input_stream=BytesIO(file_content),
                        headers=headers)
                    assert file_put_res.status_code == 200
                    file_put_data = json.loads(
                        file_put_res.get_data(as_text=True))
                    assert 'created' in file_put_data

                    bucket_id = draft_create_data['links']['files'].split(
                        '/')[-1]
                    # make sure that downloads from deposits are skipped
                    client.get(
                        url_for('invenio_files_rest.object_api',
                                bucket_id=bucket_id,
                                key=file_key))
                    assert process_events(['file-download']) == \
                        [('file-download', (0, 0))]

                # test draft submit
                draft_submit_res = client.patch(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=draft_create_data['id']),
                    data=json.dumps([{
                        "op": "replace",
                        "path": "/publication_state",
                        "value": PublicationStates.submitted.name
                    }]),
                    headers=submit_headers)
                assert draft_submit_res.status_code == 200

            with app.test_client() as client:
                login_user(com_admin, client)
                # test draft publish
                draft_publish_res = client.patch(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=draft_create_data['id']),
                    data=json.dumps([{
                        "op": "replace",
                        "path": "/publication_state",
                        "value": PublicationStates.published.name
                    }]),
                    headers=publish_headers)

                assert draft_publish_res.status_code == 200
                draft_publish_data = json.loads(
                    draft_publish_res.get_data(as_text=True))

                # Test record GET
                record_get_res = client.get(url_for(
                    'b2share_records_rest.b2rec_item',
                    pid_value=draft_publish_data['id']),
                                            headers=headers)
                assert record_get_res.status_code == 200
                record_get_data = json.loads(
                    record_get_res.get_data(as_text=True))

                # make sure that templates are in the ES
                list(current_search.put_templates())

                # test that a record is accessible through the rest api
                file1 = record_get_data['files'][0]

                # download once
                client.get(url_for('invenio_files_rest.object_api',
                                   bucket_id=file1['bucket'],
                                   key=file1['key']),
                           headers=com_admin_headers)
                # make sure that the queue contains the event
                assert list(
                    current_queues.queues['stats-file-download'].consume())

                # download again
                client.get(url_for('invenio_files_rest.object_api',
                                   bucket_id=file1['bucket'],
                                   key=file1['key']),
                           headers=com_admin_headers)

                process_events(['file-download'])
                current_search_client.indices.refresh('*')
                # make sure that new index for events is created in ES
                current_search_client.indices.exists(
                    index='events-stats-file-download')

                aggregate_events(['file-download-agg'])
                current_search_client.indices.refresh('*')

                # make sure that new aggregation index is created in ES
                current_search_client.indices.exists(
                    index='stats-file-download')

                stats_ret = client.post(url_for('invenio_stats.stat_query'),
                                        data=json.dumps({
                                            'mystat': {
                                                'stat':
                                                'bucket-file-download-total',
                                                'params': {
                                                    'start_date': '2017-01-01',
                                                    'bucket_id':
                                                    file1['bucket'],
                                                }
                                            }
                                        }),
                                        headers=stats_headers)
                stats_ret_data = json.loads(stats_ret.get_data(as_text=True))
                assert stats_ret_data['mystat']['buckets'][0]['value'] == 1.0
Example #45
0
    def setUp(self):
        from invenio_oauth2server.models import Scope
        from invenio_accounts.models import User
        from invenio_oauth2server.models import Client, Token

        from invenio_oauth2server.registry import scopes as scopes_registry

        # Register a test scope
        scopes_registry.register(Scope('test:scope1'))
        scopes_registry.register(Scope('test:scope2', internal=True))

        self.base_url = self.app.config.get('CFG_SITE_SECURE_URL')

        # Create needed objects
        u = User(email='*****@*****.**', nickname='tester')
        u.password = "******"

        self.create_objects([u])

        # environment
        #
        # resource_owner -- client1 -- token_1
        #                     |
        #                     -------- token_2
        #                               |
        #       consumer ----------------

        # create resource_owner and consumer
        self.resource_owner = User(email='*****@*****.**',
                                   nickname='resource_owner',
                                   password='******')
        self.consumer = User(email='*****@*****.**',
                             nickname='consumer',
                             password='******')

        self.create_objects([self.resource_owner, self.consumer])

        # create resource_owner -> client_1
        self.u1c1 = Client(client_id='client_test_u1c1',
                           client_secret='client_test_u1c1',
                           name='client_test_u1c1',
                           description='',
                           is_confidential=False,
                           user=self.resource_owner,
                           _redirect_uris='',
                           _default_scopes="")

        self.create_objects([self.u1c1])

        # create resource_owner -> client_1 / resource_owner -> token_1
        self.u1c1u1t1 = Token(
            client=self.u1c1,
            user=self.resource_owner,
            token_type='u',
            access_token='dev_access_1',
            refresh_token='dev_refresh_1',
            expires=None,
            is_personal=False,
            is_internal=False,
            _scopes='',
        )
        # create consumer -> client_1 / resource_owner -> token_2
        self.u1c1u2t2 = Token(
            client=self.u1c1,
            user=self.consumer,
            token_type='u',
            access_token='dev_access_2',
            refresh_token='dev_refresh_2',
            expires=None,
            is_personal=False,
            is_internal=False,
            _scopes='',
        )

        # create objects
        self.create_objects([self.u1c1u1t1, self.u1c1u2t2])

        self.objects = [
            u, self.resource_owner, self.consumer, self.u1c1u1t1, self.u1c1u2t2
        ]
Example #46
0
    def setUp(self):
        from flask_restful import Resource, fields, marshal
        from invenio_accounts.models import User
        from invenio_oauth2server.models import Token

        class TagRepresenation(object):
            """A representation of a tag.

            This class will be only used to return a tag as JSON.
            """

            marshaling_fields = dict(id=fields.Integer,
                                     name=fields.String,
                                     id_user=fields.Integer)

            def __init__(self, retrieved_tag):
                """Initialization.

                Declared the attributes to marshal with a tag.
                :param retrieved_tag: a tag from the database
                """
                # get fields from the given tag
                self.id = retrieved_tag.id
                self.name = retrieved_tag.name
                self.id_user = retrieved_tag.id_user

            def marshal(self):
                """Marshal the Tag."""
                return marshal(self, self.marshaling_fields)

        class TestTagsResource(Resource):

            method_decorators = [require_api_auth()]

            @require_header('Content-Type', 'application/json')
            def get(self):
                import json
                from flask import make_response
                from invenio_ext.restful.errors import (RestfulError,
                                                        InvalidPageError)
                from invenio_ext.restful import pagination

                response = None
                try:
                    endpoint = request.endpoint
                    args = request.args
                    page = int(args.get('page', 1))
                    per_page = int(args.get('per_page', 2))
                    # check values arguments and raise exceptions if any errors
                    if per_page < 0:
                        raise RestfulError(
                            error_msg="Invalid per_page: {}".format(per_page),
                            status_code=400)
                    if page < 0:
                        raise InvalidPageError(
                            error_msg="Invalid page: {}".format(page),
                            status_code=400)

                    # need to sort by id
                    # also assuming only one user so no need to filter
                    # user's id
                    tags_q = WtgTAGPaginationMokup()
                    p = pagination.RestfulSQLAlchemyPagination(
                        query=tags_q, page=page, per_page=per_page)
                    if page > p.pages:
                        raise InvalidPageError(
                            error_msg="Invalid page: {}".format(page),
                            status_code=400)
                    tags_to_return = map(
                        lambda x: TagRepresenation(x).marshal(), p.items)

                    kwargs = {}
                    kwargs['endpoint'] = endpoint
                    kwargs['args'] = request.args
                    link_header = p.link_header(**kwargs)
                    response = make_response(json.dumps(tags_to_return))
                    response.headers[link_header[0]] = link_header[1]
                    response.headers['Content-Type'] = request.headers[
                        'Content-Type']
                except (RestfulError, InvalidPageError) as e:
                    exception = {}
                    exception['message'] = e.error_msg
                    exception['type'] = "{0}".format(type(e))
                    response = make_response(json.dumps(exception))
                return response

        # Register API resources
        api = self.app.extensions['restful']
        api.add_resource(TestTagsResource, '/api/testtags/')

        # Create a user
        self.user = User(email='*****@*****.**', nickname='tester')
        self.user.password = "******"
        db.session.add(self.user)
        db.session.commit()

        # create token
        self.token = Token.create_personal('test-',
                                           self.user.id,
                                           scopes=[],
                                           is_internal=True)
Example #47
0
def models_fixture(app):
    """Fixture that contains the test data for models tests."""
    from invenio_oauth2server.proxies import current_oauth2server
    with app.app_context():
        # Register a test scope
        current_oauth2server.register_scope(Scope('test:scope1'))
        current_oauth2server.register_scope(Scope('test:scope2',
                                                  internal=True))
        datastore = app.extensions['security'].datastore
        with db.session.begin_nested():
            test_user = datastore.create_user(
                email='*****@*****.**',
                password='******',
            )
            resource_owner = datastore.create_user(
                email='*****@*****.**', password='******')
            consumer = datastore.create_user(
                email='*****@*****.**', password='******')

            # create resource_owner -> client_1
            u1c1 = Client(client_id='client_test_u1c1',
                          client_secret='client_test_u1c1',
                          name='client_test_u1c1',
                          description='',
                          is_confidential=False,
                          user=resource_owner,
                          _redirect_uris='',
                          _default_scopes="")
            # create resource_owner -> client_1 / resource_owner -> token_1

            u1c1u1t1 = Token(
                client=u1c1,
                user=resource_owner,
                token_type='u',
                access_token='dev_access_1',
                refresh_token='dev_refresh_1',
                expires=None,
                is_personal=False,
                is_internal=False,
                _scopes='',
            )

            # create consumer -> client_1 / resource_owner -> token_2

            u1c1u2t2 = Token(
                client=u1c1,
                user=consumer,
                token_type='u',
                access_token='dev_access_2',
                refresh_token='dev_refresh_2',
                expires=None,
                is_personal=False,
                is_internal=False,
                _scopes='',
            )
            db.session.add(u1c1)
            db.session.add(u1c1u1t1)
            db.session.add(u1c1u2t2)
        db.session.commit()
        test_user_id = test_user.get_id()
        app.test_user = lambda: User.query.get(test_user_id)
        app.resource_owner_id = resource_owner.get_id()
        app.consumer_id = consumer.get_id()
        app.u1c1_id = u1c1.client_id
        app.u1c1u1t1_id = u1c1u1t1.id
        app.u1c1u2t2_id = u1c1u2t2.id
    return app
Example #48
0
    def setUp(self):
        from invenio_accounts.models import User
        from invenio_oauth2server.registry import scopes
        from invenio_oauth2server.models import Token, Scope

        # Setup variables:
        self.called = dict()

        # Setup test scopes
        with self.app.app_context():
            scopes.register(
                Scope(
                    'test:testscope',
                    group='Test',
                    help_text='Test scope',
                ))

        # Setup API resources
        class Test1Resource(Resource):
            # NOTE: Method decorators are applied in reverse order
            method_decorators = [
                require_oauth_scopes('test:testscope'),
                require_api_auth(),
            ]

            def get(self):
                assert request.oauth.access_token
                return "success", 200

            def post(self):
                assert request.oauth.access_token
                return "success", 200

            @require_header('Content-Type', 'application/json')
            def put(self):
                return "success", 200

        class Test2Resource(Resource):
            @require_api_auth()
            @require_oauth_scopes('test:testscope')
            def get(self):
                assert request.oauth.access_token
                return "success", 200

            @require_api_auth()
            @require_oauth_scopes('test:testscope')
            def post(self):
                assert request.oauth.access_token
                return "success", 200

            @require_header('Content-Type', 'text/html')
            def put(self):
                return "success", 200

        # Register API resources
        api = self.app.extensions['restful']
        api.add_resource(Test1Resource, '/api/test1/decoratorstestcase/')
        api.add_resource(Test2Resource, '/api/test2/decoratorstestcase/')

        # Create a user
        self.user = User(email='*****@*****.**', nickname='tester')
        self.user.password = "******"
        db.session.add(self.user)
        db.session.commit()

        # Create tokens
        self.token = Token.create_personal('test-',
                                           self.user.id,
                                           scopes=['test:testscope'],
                                           is_internal=True)
        self.token_noscope = Token.create_personal('test-',
                                                   self.user.id,
                                                   scopes=[],
                                                   is_internal=True)
Example #49
0
def resource_fixture(app, api_app):
    """Fixture that contains the test data for models tests."""
    from flask import g, request
    from invenio_oauth2server.proxies import current_oauth2server

    # Setup API resources
    class Test0Resource(MethodView):
        def get(self):
            app.identity = g.identity
            return "success", 200

    class Test1Resource(MethodView):
        # NOTE: Method decorators are applied in reverse order
        decorators = [
            require_oauth_scopes('test:testscope'),
            require_api_auth(),
        ]

        def get(self):
            assert request.oauth.access_token
            app.identity = g.identity
            return "success", 200

        def post(self):
            assert request.oauth.access_token
            return "success", 200

    class Test2Resource(MethodView):
        @require_api_auth()
        @require_oauth_scopes('test:testscope')
        def get(self):
            assert request.oauth.access_token
            return "success", 200

        @require_api_auth()
        @require_oauth_scopes('test:testscope')
        def post(self):
            assert request.oauth.access_token
            return "success", 200

    class Test3Resource(MethodView):
        @require_api_auth()
        def post(self):
            return "success", 200

    class Test4Resource(MethodView):
        @require_api_auth(allow_anonymous=True)
        def get(self):
            from flask_login import current_user
            return str(current_user.get_id()), 200

        def post(self):
            from flask_login import current_user
            return str(current_user.get_id()), 200

    # Register API resources
    api_app.add_url_rule(
        '/test0/identitytestcase/',
        view_func=Test0Resource.as_view('test0resource'),
    )
    api_app.add_url_rule(
        '/test1/decoratorstestcase/',
        view_func=Test1Resource.as_view('test1resource'),
    )
    api_app.add_url_rule(
        '/test2/decoratorstestcase/',
        view_func=Test2Resource.as_view('test2resource'),
    )
    # This one is a UI resource using login_required
    api_app.add_url_rule(
        '/test3/loginrequiredstestcase/',
        view_func=Test3Resource.as_view('test3resource'),
    )
    api_app.add_url_rule(
        '/test4/allowanonymous/',
        view_func=Test4Resource.as_view('test4resource'),
    )

    datastore = app.extensions['security'].datastore
    with app.app_context():
        # Register a test scope
        current_oauth2server.register_scope(
            Scope('test:testscope', group='Test', help_text='Test scope'))
        with db.session.begin_nested():
            app.user = datastore.create_user(
                email='*****@*****.**',
                password='******',
                active=True,
            )

        # Create tokens
        app.user_id = app.user.id
        app.token = Token.create_personal('test-',
                                          app.user.id,
                                          scopes=['test:testscope'],
                                          is_internal=True).access_token
        app.token_noscope = Token.create_personal(
            'test-', app.user.id, scopes=[], is_internal=True).access_token
        db.session.commit()

    with api_app.test_request_context():
        app.url_for_test3resource = url_for('test3resource')

    with api_app.test_request_context():
        app.url_for_test0resource = url_for('test0resource')
        app.url_for_test1resource = url_for('test1resource')
        app.url_for_test2resource = url_for('test2resource')
        app.url_for_test4resource = url_for('test4resource')
        app.url_for_test0resource_token = url_for('test0resource',
                                                  access_token=app.token)
        app.url_for_test1resource_token = url_for('test1resource',
                                                  access_token=app.token)
        app.url_for_test2resource_token = url_for('test2resource',
                                                  access_token=app.token)
        app.url_for_test1resource_token_noscope = url_for(
            'test1resource', access_token=app.token_noscope)
        app.url_for_test2resource_token_noscope = url_for(
            'test2resource', access_token=app.token_noscope)
        app.url_for_test4resource_token = url_for('test4resource',
                                                  access_token=app.token)

    return app
    def setUp(self):
        super(ProviderTestCase, self).setUp()
        # Set environment variable DEBUG to true, to allow testing without
        # SSL in oauthlib.
        if self.app.config.get('CFG_SITE_SECURE_URL').startswith('http://'):
            self.os_debug = os.environ.get('OAUTHLIB_INSECURE_TRANSPORT', '')
            os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = 'true'

        from invenio_accounts.models import User
        from invenio_oauth2server.models import Client, Scope
        from invenio_oauth2server.registry import scopes as scopes_registry

        # Register a test scope
        scopes_registry.register(Scope('test:scope'))

        self.base_url = self.app.config.get('CFG_SITE_SECURE_URL')

        # Create needed objects
        u = User(
            email='*****@*****.**', nickname='tester'
        )
        u.password = "******"

        u2 = User(
            email='*****@*****.**', nickname='tester2'
        )
        u2.password = "******"

        db.session.add(u)
        db.session.add(u2)

        c1 = Client(
            client_id='dev',
            client_secret='dev',
            name='dev',
            description='',
            is_confidential=False,
            user=u,
            _redirect_uris='%s/oauth2test/authorized' % self.base_url,
            _default_scopes="test:scope"
        )

        c2 = Client(
            client_id='confidential',
            client_secret='confidential',
            name='confidential',
            description='',
            is_confidential=True,
            user=u,
            _redirect_uris='%s/oauth2test/authorized' % self.base_url,
            _default_scopes="test:scope"
        )

        db.session.add(c1)
        db.session.add(c2)

        db.session.commit()

        self.objects = [u, u2, c1, c2]

        # Create a personal access token as well.
        from invenio_oauth2server.models import Token
        self.personal_token = Token.create_personal(
            'test-personal', 1, scopes=[], is_internal=True
        )