def test_get_create_remote_account(app, example):
    """Test create remote account."""
    created_acc = RemoteAccount.create(1, "dev", dict(somekey="somevalue"))
    assert created_acc

    retrieved_acc = RemoteAccount.get(1, "dev")
    assert created_acc.id == retrieved_acc.id
    assert retrieved_acc.extra_data == dict(somekey="somevalue")

    db.session.delete(retrieved_acc)
    assert RemoteAccount.get(1, "dev") is None
def test_get_create_remote_account(models_fixture):
    """Test create remote account."""
    app = models_fixture
    created_acc = RemoteAccount.create(1, 'dev', dict(somekey='somevalue'))
    assert created_acc

    retrieved_acc = RemoteAccount.get(1, 'dev')
    assert created_acc.id == retrieved_acc.id
    assert retrieved_acc.extra_data == dict(somekey='somevalue')

    db.session.delete(retrieved_acc)
    assert RemoteAccount.get(1, 'dev') is None
    def test_get_create(self):
        from invenio_oauthclient.models import RemoteAccount

        created_acc = RemoteAccount.create(1, "dev", dict(somekey="somevalue"))
        assert created_acc

        retrieved_acc = RemoteAccount.get(1, "dev")
        assert created_acc.id == retrieved_acc.id
        assert retrieved_acc.extra_data == dict(somekey="somevalue")

        db.session.delete(retrieved_acc)
        assert RemoteAccount.get(1, "dev") is None
Example #4
0
def on_identity_changed(sender, identity):
    """Store groups in session whenever identity changes.

    :param identity: The user identity where information are stored.
    """
    if isinstance(identity, AnonymousIdentity):
        return

    client_id = current_app.config['CERN_APP_CREDENTIALS']['consumer_key']
    account = RemoteAccount.get(
        user_id=current_user.get_id(),
        client_id=client_id,
    )
    groups = []
    if account:
        remote = find_remote_by_client_id(client_id)
        resource = get_resource(remote)
        refresh = current_app.config.get(
            'OAUTHCLIENT_CERN_REFRESH_TIMEDELTA',
            OAUTHCLIENT_CERN_REFRESH_TIMEDELTA
        )
        groups.extend(
            account_groups(account, resource, refresh_timedelta=refresh)
        )

    extend_identity(identity, groups)
def test_get_create_remote_token(app, example):
    """Test create remote token."""
    existing_email = "*****@*****.**"
    datastore = app.extensions["invenio-accounts"].datastore
    user = datastore.find_user(email=existing_email)

    t = RemoteToken.create(user.id, "dev", "mytoken", "mysecret")
    assert t
    assert t.token() == ("mytoken", "mysecret")

    acc = RemoteAccount.get(user.id, "dev")
    assert acc
    assert t.remote_account.id == acc.id
    assert t.token_type == ""

    t2 = RemoteToken.create(user.id, "dev", "mytoken2", "mysecret2", token_type="t2")
    assert t2.remote_account.id == acc.id
    assert t2.token_type == "t2"

    t3 = RemoteToken.get(user.id, "dev")
    t4 = RemoteToken.get(user.id, "dev", token_type="t2")
    assert t4.token() != t3.token()

    assert RemoteToken.query.count() == 2
    acc.delete()
    assert RemoteToken.query.count() == 0
def test_get_create_remote_token(models_fixture):
    """Test create remote token."""
    app = models_fixture
    existing_email = "*****@*****.**"
    datastore = app.extensions['invenio-accounts'].datastore
    user = datastore.find_user(email=existing_email)

    t = RemoteToken.create(user.id, "dev", "mytoken", "mysecret")
    assert t
    assert t.token() == ('mytoken', 'mysecret')

    acc = RemoteAccount.get(user.id, "dev")
    assert acc
    assert t.remote_account.id == acc.id
    assert t.token_type == ''

    t2 = RemoteToken.create(
        user.id, "dev", "mytoken2", "mysecret2",
        token_type='t2'
    )
    assert t2.remote_account.id == acc.id
    assert t2.token_type == 't2'

    t3 = RemoteToken.get(user.id, "dev")
    t4 = RemoteToken.get(user.id, "dev", token_type="t2")
    assert t4.token() != t3.token()

    assert RemoteToken.query.count() == 2
    acc.delete()
    assert RemoteToken.query.count() == 0
    def test_get_create(self):
        from invenio_oauthclient.models import RemoteAccount, RemoteToken

        t = RemoteToken.create(self.u1, "dev", "mytoken", "mysecret")
        assert t
        assert t.token() == ('mytoken', 'mysecret')

        acc = RemoteAccount.get(self.u1, "dev")
        assert acc
        assert t.remote_account.id == acc.id
        assert t.token_type == ''

        t2 = RemoteToken.create(
            self.u1, "dev", "mytoken2", "mysecret2",
            token_type='t2'
        )
        assert t2.remote_account.id == acc.id
        assert t2.token_type == 't2'

        t3 = RemoteToken.get(self.u1, "dev")
        t4 = RemoteToken.get(self.u1, "dev", token_type="t2")
        assert t4.token() != t3.token()

        assert RemoteToken.query.count() == 2
        acc.delete()
        assert RemoteToken.query.count() == 0
    def test_settings_view(self):
        # Create a remove account (linked account)
        from invenio_oauthclient.models import RemoteAccount
        RemoteAccount.create(1, 'testid', None)

        self.assert401(self.client.get(url_for('oauthclient_settings.index'),
                                       follow_redirects=True))
        self.login("admin", "")

        res = self.client.get(url_for('oauthclient_settings.index'))
        self.assert200(res)
        assert 'MyLinkedTestAccount' in res.data
        assert url_for('oauthclient.disconnect', remote_app='test') in res.data
        assert url_for('oauthclient.login', remote_app='full') in res.data
        assert url_for('oauthclient.login', remote_app='test_invalid') in \
            res.data
Example #9
0
def g_remoteaccounts(app, db, g_remoteaccounts_data):
    """Fixture for RemoteAccount objects."""
    for rad in g_remoteaccounts_data:
        ra = RemoteAccount.create(rad['user_id'], 'changeme',
                                  rad['extra_data'])
        db.session.add(ra)
        db.session.commit()
        rad['id'] = ra.id
    return g_remoteaccounts_data
def test_repr(models_fixture):
    """Test representation of RemoteAccount adn RemoteToken."""
    datastore = models_fixture.extensions['invenio-accounts'].datastore
    user = datastore.find_user(email='*****@*****.**')

    assert 'Remote Token <token_type=type access_token=mytoken>' == \
           repr(RemoteToken.create(user.id, 'dev',
                                   'mytoken', 'mysecret',
                                   token_type='type'))

    assert 'Remote Account <id=1, user_id=1>' == \
           repr(RemoteAccount.get(user.id, 'dev'))
def test_settings_view(views_fixture):
    """Test settings view."""
    app = views_fixture
    app.login_manager.login_view = None
    login_manager = app.login_manager
    datastore = app.extensions['invenio-accounts'].datastore

    @login_manager.user_loader
    def load_user(user_id):
        return user

    @app.route('/foo_login')
    def login():
        user = datastore.find_user(email='*****@*****.**')
        login_user(user)
        return 'Logged In'

    with app.app_context():
        with app.test_client() as client:
            user = datastore.find_user(email='*****@*****.**')
            RemoteAccount.create(user.get_id(), 'testid', None)

            resp = client.get(url_for('invenio_oauthclient_settings.index'),
                              follow_redirects=False)
            assert resp.status_code == 401

            # make a fake login (using my login function)
            client.get('/foo_login', follow_redirects=True)

            resp = client.get(url_for('invenio_oauthclient_settings.index'),
                              follow_redirects=True)
            assert resp.status_code == 200
            assert b'MyLinkedTestAccount' in resp.data
            assert url_for('invenio_oauthclient.disconnect',
                           remote_app='test') in resp.data.decode('utf-8')
            assert url_for('invenio_oauthclient.login',
                           remote_app='full') in resp.data.decode('utf-8')
            assert url_for(
                'invenio_oauthclient.login',
                remote_app='test_invalid') in resp.data.decode('utf-8')
def test_settings_view():
    """Test settings view."""
    app = setup_app()
    app.login_manager.login_view = None
    login_manager = app.login_manager
    datastore = app.extensions['invenio-accounts'].datastore
    datastore.create_user(email="*****@*****.**", password="******")
    user = datastore.find_user(email="*****@*****.**")

    @login_manager.user_loader
    def load_user(user_id):
        return user

    @app.route('/foo_login')
    def login():
        login_user(user)
        return "Logged In"

    with app.test_client() as client:
        # Create a remove account (linked account)
        RemoteAccount.create(user.id, 'testid', None)

        resp = client.get(url_for('invenio_oauthclient_settings.index'),
                          follow_redirects=False)
        assert resp.status_code == 401

        # make a fake login (using my login function)
        client.get('/foo_login', follow_redirects=True)

        resp = client.get(url_for('invenio_oauthclient_settings.index'),
                          follow_redirects=True)
        assert resp.status_code == 200
        assert b'MyLinkedTestAccount' in resp.data
        assert url_for('invenio_oauthclient.disconnect',
                       remote_app='test') in resp.data.decode("utf-8")
        assert url_for('invenio_oauthclient.login',
                       remote_app='full') in resp.data.decode("utf-8")
        assert url_for('invenio_oauthclient.login',
                       remote_app='test_invalid') in resp.data.decode("utf-8")
Example #13
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    orcid = account.extra_data.get('orcid')

    if orcid:
        oauth_unlink_external_id(dict(id=orcid, method='orcid'))
    if account:
        with db.session.begin_nested():
            account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
Example #14
0
def _disconnect(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    external_id = account.extra_data.get("external_id")

    if external_id:
        oauth_unlink_external_id(dict(id=external_id, method="cern_openid"))
    if account:
        with db.session.begin_nested():
            account.delete()

    disconnect_identity(g.identity)
Example #15
0
def patrons(app, db):
    """Create a patron user."""
    db.session.execute("ALTER SEQUENCE IF EXISTS accounts_user_id_seq RESTART")
    db.session.commit()

    user = User(**dict(email="*****@*****.**", active=True))
    db.session.add(user)
    db.session.commit()

    user_id = user.id

    identity = UserIdentity(**dict(id="1", method="cern", id_user=user_id))
    db.session.add(identity)

    profile = UserProfile(**dict(
        user_id=user_id,
        _displayname="id_" + str(user_id),
        full_name="System User",
    ))
    db.session.add(profile)

    client_id = app.config["CERN_APP_OPENID_CREDENTIALS"]["consumer_key"]
    remote_account = RemoteAccount(client_id=client_id,
                                   **dict(
                                       user_id=user_id,
                                       extra_data=dict(person_id="1",
                                                       department="Department",
                                                       legacy_id="1"),
                                   ))
    db.session.add(remote_account)
    db.session.commit()

    user2 = User(**dict(email="*****@*****.**", active=True))
    db.session.add(user2)
    db.session.commit()

    user2_id = user2.id

    profile = UserProfile(**dict(
        user_id=user2_id,
        _displayname="id_" + str(user2_id),
        full_name="System User",
    ))
    db.session.add(profile)
    db.session.commit()

    return user, user2
Example #16
0
def github_remote_accounts(datadir, users, db):
    """Load GitHub remote account objects."""
    # Create records and PIDs for GitHub releases
    for recid in ('100', '101', '200', '201'):
        r = Record.create({})
        PersistentIdentifier.create('recid', recid, object_uuid=r.id)
    db.session.commit()

    with open(join(datadir, 'github_remote_accounts.json')) as fp:
        gh_remote_accounts = json.load(fp)
    remote_accounts = []
    for idx, gh_ra in enumerate(gh_remote_accounts):
        assert users[idx]['id'] == gh_ra['user_id']
        ra = RemoteAccount.create(gh_ra['user_id'], 'clientid',
                                  gh_ra['extra_data'])
        remote_accounts.append(ra)
    return remote_accounts
Example #17
0
def test_utilities(models_fixture):
    """Test utilities."""
    app = models_fixture
    datastore = app.extensions['invenio-accounts'].datastore
    assert obj_or_import_string('invenio_oauthclient.errors')

    # User
    existing_email = '*****@*****.**'
    user = datastore.find_user(email=existing_email)

    # Authenticate
    assert not _get_external_id({})
    assert not oauth_authenticate('dev', user, require_existing_link=True)

    _security.confirmable = True
    _security.login_without_confirmation = False
    user.confirmed_at = None
    assert not oauth_authenticate('dev', user)

    # Tokens
    t = RemoteToken.create(user.id, 'dev', 'mytoken', 'mysecret')
    assert \
        RemoteToken.get(user.id, 'dev', access_token='mytoken') == \
        RemoteToken.get_by_token('dev', 'mytoken')

    assert oauth_get_user('dev', access_token=t.access_token) == user
    assert \
        oauth_get_user('dev', account_info={'user': {'email': existing_email}}) == user

    # Link user to external id
    external_id = {'id': '123', 'method': 'test_method'}
    oauth_link_external_id(user, external_id)

    with pytest.raises(AlreadyLinkedError):
        oauth_link_external_id(user, external_id)

    assert oauth_get_user('dev',
                          account_info={
                              'external_id': external_id['id'],
                              'external_method': external_id['method']
                          }) == user

    # Cleanup
    oauth_unlink_external_id(external_id)
    acc = RemoteAccount.get(user.id, 'dev')
    acc.delete()
Example #18
0
def test_utilities(models_fixture):
    """Test utilities."""
    app = models_fixture
    datastore = app.extensions['invenio-accounts'].datastore
    assert obj_or_import_string('invenio_oauthclient.errors')

    # User
    existing_email = '*****@*****.**'
    user = datastore.find_user(email=existing_email)

    # Authenticate
    assert not _get_external_id({})
    assert not oauth_authenticate('dev', user, require_existing_link=True)

    _security.confirmable = True
    _security.login_without_confirmation = False
    user.confirmed_at = None
    assert not oauth_authenticate('dev', user)

    # Tokens
    t = RemoteToken.create(user.id, 'dev', 'mytoken', 'mysecret')
    assert \
        RemoteToken.get(user.id, 'dev', access_token='mytoken') == \
        RemoteToken.get_by_token('dev', 'mytoken')

    assert oauth_get_user('dev', access_token=t.access_token) == user
    assert \
        oauth_get_user('dev', account_info={'user': {'email': existing_email}}) == user

    # Link user to external id
    external_id = {'id': '123', 'method': 'test_method'}
    oauth_link_external_id(user, external_id)

    with pytest.raises(AlreadyLinkedError):
        oauth_link_external_id(user, external_id)

    assert oauth_get_user('dev',
                          account_info={
                              'external_id': external_id['id'],
                              'external_method': external_id['method']
                          }) == user

    # Cleanup
    oauth_unlink_external_id(external_id)
    acc = RemoteAccount.get(user.id, 'dev')
    acc.delete()
Example #19
0
def github_remote_accounts(datadir, users, db):
    """Load GitHub remote account objects."""
    # Create records and PIDs for GitHub releases
    for recid in ('100', '101', '200', '201'):
        r = Record.create({})
        PersistentIdentifier.create('recid', recid, object_uuid=r.id)
    db.session.commit()

    with open(join(datadir, 'github_remote_accounts.json')) as fp:
        gh_remote_accounts = json.load(fp)
    remote_accounts = []
    for idx, gh_ra in enumerate(gh_remote_accounts):
        assert users[idx]['id'] == gh_ra['user_id']
        ra = RemoteAccount.create(gh_ra['user_id'], 'clientid',
                                  gh_ra['extra_data'])
        remote_accounts.append(ra)
    return remote_accounts
Example #20
0
def _disconnect(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    :param remote: The remote application.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    orcid = account.extra_data.get('orcid')

    if orcid:
        oauth_unlink_external_id({'id': orcid, 'method': 'orcid'})
    if account:
        with db.session.begin_nested():
            account.delete()
Example #21
0
def mock_user(app, request):

    def teardown(app):
        with app.app_context():
            user = User.query.filter_by(email='*****@*****.**').first()
            token = RemoteToken.query.filter_by(access_token='123').first()
            user_identity = UserIdentity.query.filter_by(
                id='0000-0001-9412-8627', method='orcid').first()
            remote_account = RemoteAccount.query.filter_by(user_id=user.id).first()
            with db.session.begin_nested():
                db.session.delete(token)
                db.session.delete(user_identity)
                db.session.delete(remote_account)
                db.session.delete(user)
            db.session.commit()

    request.addfinalizer(lambda: teardown(app))

    user = User(
        email='*****@*****.**',
    )
    db.session.add(user)
    db.session.commit()

    token = RemoteToken(
        id_remote_account=1,
        access_token='123'
    )
    user_identity = UserIdentity(
        id='0000-0001-9412-8627',
        id_user=str(user.id),
        method='orcid')
    remote_account = RemoteAccount(
        id=1,
        user_id=user.id,
        extra_data={},
        client_id=1,
        user=user)
    with app.app_context():
        with db.session.begin_nested():
            db.session.add(user_identity)
            db.session.add(remote_account)
            db.session.add(token)
        db.session.commit()
    return MockUser(app)
Example #22
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    external_id = account.extra_data.get('external_id')

    if external_id:
        oauth_unlink_external_id(dict(id=external_id, method='cern'))
    if account:
        with db.session.begin_nested():
            account.delete()

    disconnect_identity(g.identity)

    return redirect(url_for('invenio_oauthclient_settings.index'))
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    from invenio_oauthclient.utils import oauth_unlink_external_id
    from invenio_oauthclient.models import RemoteAccount

    if not current_user.is_authenticated():
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    orcid = account.extra_data.get('orcid')

    if orcid:
        oauth_unlink_external_id(dict(id=orcid, method='orcid'))
    if account:
        account.delete()

    return redirect(url_for('oauthclient_settings.index'))
Example #24
0
def _disconnect(remote, *args, **kwargs):
    """Common logic for handling disconnection of remote accounts."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)

    keycloak_id = account.extra_data.get("keycloak_id")

    if keycloak_id:
        external_id = {"id": keycloak_id, "method": remote.name}

        oauth_unlink_external_id(external_id)

    if account:
        with db.session.begin_nested():
            account.delete()
Example #25
0
    def handle_disconnect(self, remote, *args, **kwargs):
        """Handle unlinking of remote account.

        :param remote: The remote application.
        """
        if not current_user.is_authenticated:
            return current_app.login_manager.unauthorized()

        account = RemoteAccount.get(user_id=current_user.get_id(),
                                    client_id=remote.consumer_key)
        sub = account.extra_data.get('sub')

        if sub:
            oauth_unlink_external_id({'id': sub, 'method': self.name})
        if account:
            with db.session.begin_nested():
                account.delete()

        return redirect(url_for('invenio_oauthclient_settings.index'))
Example #26
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    remote_account = RemoteAccount.get(user_id=current_user.get_id(),
                                       client_id=remote.consumer_key)
    external_method = 'github'
    external_ids = [i.id for i in current_user.external_identifiers
                    if i.method == external_method]

    if external_ids:
        oauth_unlink_external_id(dict(id=external_ids[0],
                                      method=external_method))
    if remote_account:
        with db.session.begin_nested():
            remote_account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
def test_utilities(models_fixture):
    """Test utilities."""
    app = models_fixture
    datastore = app.extensions["invenio-accounts"].datastore
    assert obj_or_import_string("invenio_oauthclient.errors")

    # User
    existing_email = "*****@*****.**"
    user = datastore.find_user(email=existing_email)

    # Authenticate
    assert not _get_external_id({})
    assert not oauth_authenticate("dev", user, require_existing_link=True)

    _security.confirmable = True
    _security.login_without_confirmation = False
    user.confirmed_at = None
    assert not oauth_authenticate("dev", user)

    # Tokens
    t = RemoteToken.create(user.id, "dev", "mytoken", "mysecret")
    assert RemoteToken.get(user.id, "dev", access_token="mytoken") == RemoteToken.get_by_token("dev", "mytoken")

    assert oauth_get_user("dev", access_token=t.access_token) == user
    assert oauth_get_user("dev", account_info={"user": {"email": existing_email}}) == user

    # Link user to external id
    external_id = {"id": "123", "method": "test_method"}
    oauth_link_external_id(user, external_id)

    with pytest.raises(AlreadyLinkedError):
        oauth_link_external_id(user, external_id)

    assert (
        oauth_get_user("dev", account_info={"external_id": external_id["id"], "external_method": external_id["method"]})
        == user
    )

    # Cleanup
    oauth_unlink_external_id(external_id)
    acc = RemoteAccount.get(user.id, "dev")
    acc.delete()
Example #28
0
def _disconnect(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    :param remote: The remote application.
    :returns: The HTML response.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    remote_account = RemoteAccount.get(user_id=current_user.get_id(),
                                       client_id=remote.consumer_key)
    external_method = 'github'
    external_ids = [i.id for i in current_user.external_identifiers
                    if i.method == external_method]

    if external_ids:
        oauth_unlink_external_id(dict(id=external_ids[0],
                                      method=external_method))
    if remote_account:
        with db.session.begin_nested():
            remote_account.delete()
Example #29
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    This default handler will just delete the remote account link. You may
    wish to extend this module to perform clean-up in the remote service
    before removing the link (e.g. removing install webhooks).

    :param remote: The remote application.
    :returns: Redirect response.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    with db.session.begin_nested():
        account = RemoteAccount.get(user_id=current_user.get_id(),
                                    client_id=remote.consumer_key)
        if account:
            account.delete()

    db.session.commit()
    return redirect('/')
Example #30
0
def on_identity_changed(sender, identity):
    """Store roles in session whenever identity changes.

    :param identity: The user identity where information are stored.
    """
    if isinstance(identity, AnonymousIdentity):
        disconnect_identity(identity)
        return

    remote = g.get("oauth_logged_in_with_remote", None)
    if not remote or remote.name != "cern_openid":
        # signal coming from another remote app
        return

    logged_in_via_token = hasattr(current_user, 'login_via_oauth2') \
        and getattr(current_user, 'login_via_oauth2')

    client_id = current_app.config["CERN_APP_OPENID_CREDENTIALS"][
        "consumer_key"]
    remote_account = RemoteAccount.get(user_id=current_user.get_id(),
                                       client_id=client_id)
    roles = []

    if remote_account and not logged_in_via_token:
        refresh = current_app.config.get(
            "OAUTHCLIENT_CERN_OPENID_REFRESH_TIMEDELTA",
            OAUTHCLIENT_CERN_OPENID_REFRESH_TIMEDELTA,
        )
        if refresh:
            resource = get_resource(remote)
            roles.extend(
                account_roles_and_extra_data(remote_account,
                                             resource,
                                             refresh_timedelta=refresh))
        else:
            roles.extend(remote_account.extra_data["roles"])
    elif remote_account and logged_in_via_token:
        roles.extend(remote_account.extra_data["roles"])

    extend_identity(identity, roles)
Example #31
0
def import_users_from_json(dump_file):
    """Imports additional user data from JSON."""
    dump_file = dump_file[0]
    with click.progressbar(json.load(dump_file)) as bar:
        for record in bar:
            click.echo('Importing user "{0}({1})"...'.format(
                record["id"], record["email"]))
            ccid = record.get("ccid")
            if not ccid:
                click.secho(
                    "User {0}({1}) does not have ccid".format(
                        record["id"], record["email"]),
                    fg="magenta",
                )
                continue
            user = get_user_by_person_id(ccid)
            if not user:
                click.secho(
                    "User {0}({1}) not synced via LDAP".format(
                        record["id"], record["email"]),
                    fg="yellow",
                )
                continue
                # todo uncomment when more data
                # raise UserMigrationError
            else:
                client_id = current_app.config["CERN_APP_OPENID_CREDENTIALS"][
                    "consumer_key"]
                account = RemoteAccount.get(user_id=user.id,
                                            client_id=client_id)
                extra_data = account.extra_data
                if "legacy_id" in extra_data:
                    del extra_data["legacy_id"]
                # add legacy_id information
                account.extra_data.update(legacy_id=str(record["id"]),
                                          **extra_data)
                db.session.add(account)
                patron = Patron(user.id)
                PatronIndexer().index(patron)
        db.session.commit()
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    This default handler will just delete the remote account link. You may
    wish to extend this module to perform clean-up in the remote service
    before removing the link (e.g. removing install webhooks).

    :param remote: The remote application.
    :returns: Redirect response.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    with db.session.begin_nested():
        account = RemoteAccount.get(
            user_id=current_user.get_id(),
            client_id=remote.consumer_key
        )
        if account:
            account.delete()

    db.session.commit()
    return redirect('/')
Example #33
0
def on_identity_changed(sender, identity):
    """Store groups in session whenever identity changes.

    :param identity: The user identity where information are stored.
    """
    if isinstance(identity, AnonymousIdentity):
        return

    client_id = current_app.config['CERN_APP_CREDENTIALS']['consumer_key']
    account = RemoteAccount.get(
        user_id=current_user.get_id(),
        client_id=client_id,
    )
    groups = []
    if account:
        remote = find_remote_by_client_id(client_id)
        resource = get_resource(remote)
        refresh = current_app.config.get('OAUTHCLIENT_CERN_REFRESH_TIMEDELTA',
                                         OAUTHCLIENT_CERN_REFRESH_TIMEDELTA)
        groups.extend(
            account_groups(account, resource, refresh_timedelta=refresh))

    extend_identity(identity, groups)
Example #34
0
def system_user(app, db):
    """Create a regular system user."""
    user = User(**dict(email="*****@*****.**", active=True))
    db.session.add(user)
    db.session.commit()

    user_id = user.id

    identity = UserIdentity(**dict(id="1", method="cern", id_user=user_id))
    db.session.add(identity)

    profile = UserProfile(**dict(user_id=user_id,
                                 _displayname="id_" + str(user_id),
                                 full_name="System User"))
    db.session.add(profile)

    remote_account = RemoteAccount(client_id="CLIENT_ID",
                                   **dict(user_id=user_id,
                                          extra_data=dict(
                                              person_id="1",
                                              department="Department")))
    db.session.add(remote_account)
    db.session.commit()
    return user
Example #35
0
 def account(self):
     """Return remote account."""
     return RemoteAccount.get(self.user_id, self.remote.consumer_key)
Example #36
0
def get_account(user_id=None):
    """Retrieve linked GitHub account."""
    return RemoteAccount.get(user_id or current_user.get_id(), get_client_id())
Example #37
0
def test_identity_changed(app_rest, example_cern_openid_rest, models_fixture):
    def _init():
        ioc = app_rest.extensions['oauthlib.client']

        # setup the user account via cern_openid
        with app_rest.test_client() as c:
            # Ensure remote apps have been loaded (due to before first request)
            resp = c.get(
                url_for('invenio_oauthclient.rest_login',
                        remote_app='cern_openid'))
            assert resp.status_code == 302

            example_response, example_token, example_account_info = \
                example_cern_openid_rest

            mock_response(app_rest.extensions['oauthlib.client'],
                          'cern_openid', example_token)
            mock_remote_get(ioc, 'cern_openid', example_response)

            resp = c.get(
                url_for('invenio_oauthclient.rest_authorized',
                        remote_app='cern_openid',
                        code='test',
                        state=get_state('cern_openid')))
            assert resp.status_code == 302
            expected_url_args = {
                "message": "Successfully authorized.",
                "code": 200,
            }
            check_response_redirect_url_args(resp, expected_url_args)

            assert len(g.identity.provides) == 3

    def _test_with_token(user, remote_account):
        with app_rest.test_request_context():
            # mark user as logged in via token
            user.login_via_oauth2 = True
            # check if the initial roles are there
            login_user(user)

            assert current_user.login_via_oauth2

            assert len(g.identity.provides) == 3
            logout_user()

            # remove the cern roles
            remote_account.extra_data.update(roles=[])

            # login the user again
            login_user(user)

            # check if the cern roles are not fetched from the provider
            assert len(g.identity.provides) == 2
            logout_user()

    def _test_without_token(user, remote_account):
        user.login_via_oauth2 = False

        current_app.config['OAUTHCLIENT_CERN_OPENID_REFRESH_TIMEDELTA'] = False
        login_user(user)

        # check that the roles are not refreshed from provider
        assert len(g.identity.provides) == 2
        logout_user()

        current_app.config['OAUTHCLIENT_CERN_OPENID_REFRESH_TIMEDELTA'] \
            = timedelta(microseconds=1)
        login_user(user)

        # check if roles refreshed from the provider
        assert len(g.identity.provides) == 3

    _init()

    datastore = app_rest.extensions['invenio-accounts'].datastore
    user = datastore.find_user(email='*****@*****.**')
    assert user

    client_id = current_app.config["CERN_APP_OPENID_CREDENTIALS"][
        "consumer_key"]
    # make sure the roles are cleaned
    remote_account = RemoteAccount.get(user_id=user.get_id(),
                                       client_id=client_id)

    _test_with_token(user, remote_account)
    _test_without_token(user, remote_account)
Example #38
0
 def account(self):
     """Return remote account."""
     return RemoteAccount.get(self.user_id, self.remote.consumer_key)