GithubHelp home page GithubHelp logo

inveniosoftware / invenio-oauthclient Goto Github PK

View Code? Open in Web Editor NEW
6.0 85.0 73.0 992 KB

Invenio module that provides OAuth web authorization support.

Home Page: https://invenio-oauthclient.readthedocs.io

License: MIT License

Python 95.79% HTML 3.81% Shell 0.40%

invenio-oauthclient's Introduction

Invenio-OAuthClient

image

image

image

image

Invenio module that provides OAuth web authorization support.

OAuth client support is typically used to allow features such as social login (e.g. Sign in with Twitter) and access to resources owned by a specific user at a remote service. Both OAuth 1.0 and OAuth 2.0 are supported.

Features:

  • Views: OAuth login and authorized endpoints, linked account settings and sign-up handling.
  • Client: A client to interact with remote applications.
  • Contrib: Ready-to-use GitHub, ORCID, and CERN remote applications.
  • Models: Persistence layer for OAuth access tokens including support for storing extra data together with a token.
  • Handlers: Customizable handlers for deciding what happens when a user authorizes a request.

Further documentation is available on https://invenio-oauthclient.readthedocs.io/

invenio-oauthclient's People

Contributors

alizeepace avatar carantunes avatar chiarabi avatar crepererum avatar drjova avatar glignos avatar hachreak avatar hjhsalo avatar inveniobot avatar javierdelgadofernandez avatar jirikuncar avatar jmartinm avatar jrcastro2 avatar kpsherva avatar lnielsen avatar ludmilamarian avatar max-moser avatar mb-wali avatar mesemus avatar mvidalgarcia avatar ntarocco avatar omelkonian avatar pamfilos avatar samihiltunen avatar slint avatar tiborsimko avatar tlgino avatar topless avatar utnapischtim avatar zzacharo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

invenio-oauthclient's Issues

api: stabilise and document

  • check existing API functionality
  • add missing important API functionality
  • check API function signatures and parameters
  • enhance API docstrings (param, returns, raises, versionadded)
  • plug API functions to existing docs

models: "RemoteToken.access_token" visible in repr

The RemoteToken.access_token variable is part of the repr string of the object which is problematic since one could use the access_token for performing any kind of authorized request on the remote application's API (e.g. GitHub).

It should generally be treated as a password field which means that it should not be displayed in plaintext in logs or any kind of object representation.

orcid: link account fails

Reproduce:

  • Login account A
  • Connect account A with ORCID account X
  • Logout
  • Login account B
  • Connect account B with ORCID account X 💥
Traceback (most recent call last):
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/werkzeug/wsgi.py", line 659, in __call__
    return app(environ, start_response)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
    return view_func(**req.view_args)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/views/client.py", line 129, in authorized
    return current_oauthclient.handlers[remote_app]()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/flask_oauthlib/client.py", line 647, in decorated
    return f(*((data,) + args), **kwargs)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/handlers.py", line 426, in inner
    return f(args[0], remote, *args[1:], **kwargs)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/handlers.py", line 181, in inner
    return f(*args, **kwargs)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/handlers.py", line 222, in authorized_signup_handler
    token = response_token_setter(remote, resp)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/handlers.py", line 71, in response_token_setter
    return oauth2_token_setter(remote, resp)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/handlers.py", line 106, in oauth2_token_setter
    extra_data=extra_data,
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/handlers.py", line 130, in token_setter
    token_type=token_type, extra_data=extra_data
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/invenio_oauthclient/models.py", line 217, in create
    db.session.add(token)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 490, in __exit__
    self.rollback()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
    raise value
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 487, in __exit__
    self.commit()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 392, in commit
    self._prepare_impl()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 372, in _prepare_impl
    self.session.flush()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 2019, in flush
    self._flush(objects)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 2137, in _flush
    transaction.rollback(_capture_exception=True)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
    raise value
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 2101, in _flush
    flush_context.execute()
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/unitofwork.py", line 373, in execute
    rec.execute(self)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/unitofwork.py", line 532, in execute
    uow
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/persistence.py", line 174, in save_obj
    mapper, table, insert)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/orm/persistence.py", line 800, in _emit_insert_statements
    execute(statement, params)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 914, in execute
    return meth(self, multiparams, params)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1010, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1146, in _execute_context
    context)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1341, in _handle_dbapi_exception
    exc_info
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 202, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 185, in reraise
    raise value.with_traceback(tb)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context
    context)
  File "/Users/lnielsen/envs/zenoodo/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) duplicate key value violates unique constraint "oauthclient_remoteaccount_pkey"
DETAIL:  Key (id)=(3) already exists.
 [SQL: 'INSERT INTO oauthclient_remoteaccount (user_id, client_id, extra_data) VALUES (%(user_id)s, %(client_id)s, %(extra_data)s) RETURNING oauthclient_remoteaccount.id'] [parameters: {'user_id': 176, 'client_id': '…….', 'extra_data': '{}'}]

global: make it possible to disable "/account/settings" blueprint

Currently invenio_accounts.views.settings.blueprint gets automatically registered (because of the setup.py entrypoint). It should be possible via config to decide this. A temporary workaround is something like:

# ...in your module's init_app
from flask import request
@app.before_request
def disable_account_settings():
    if request.endpoint == 'invenio_accounts.settings':
        abort(404)

cern: disconnection needs an extra redirect

At CERN, the login process using OAuth creates a cookie when on the domain login.cern.ch.
This means that to complete a logout, that cookie needs to be removed.

Invenio-oauthclient cern is missing a redirect to https://login.cern.ch/adfs/ls/?wa=wsignout1.0 when logging out so that cookie is deleted. Currently, we redirect to the homepage: https://github.com/inveniosoftware/invenio-oauthclient/blob/master/invenio_oauthclient/contrib/cern.py#L293

Without this extra step, the cookie is not cleaned.

global: check-up and clean

  • Check that settings nicely integrate with accounts settings (Linked accounts)
  • Add template macros so that login buttons for each service appears the login page.

Typo in README

OAuth client support is typically used to allow features such as social login (e.g. Sign in with Twitter) and access to resources owner by a specific user at a remote service.

should say:

OAuth client support is typically used to allow features such as social login (e.g. Sign in with Twitter) and access to resources owned by a specific user at a remote service.

correct?

need release to fix OAuthLib version incompatibility

A release of invenio-oauthclient is needed.

Problem description:
invenio-oauth2server>=1.0.0a5 depends on Flask-OAuthlib>=0.9.3

PR #61 also makes this change in invenio-oauthclient but its last release still asks for Flask-OAuthlib>=0.6.0,<0.7

Thus the two of them cannot be installed together.

cern: 'Groups' not available

Traceback (most recent call last):
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 135, in handle
    self.handle_request(listener, req, client, addr)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 176, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/werkzeug/wsgi.py", line 660, in __call__
    return app(environ, start_response)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/views/client.py", line 128, in authorized
    return current_oauthclient.handlers[remote_app]()
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/flask_oauthlib/client.py", line 703, in decorated
    return f(*((data,) + args), **kwargs)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/handlers.py", line 503, in inner
    return f(args[0], remote, *args[1:], **kwargs)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/handlers.py", line 235, in inner
    return f(*args, **kwargs)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/handlers.py", line 343, in authorized_signup_handler
    account_setup = handlers['setup'](token, resp)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/handlers.py", line 505, in inner
    return f(remote, *args, **kwargs)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/contrib/cern.py", line 317, in account_setup
    groups = account_groups(token.remote_account, resource)
  File "/Users/ioannistsanaktsidis/Envs/cap-new/lib/python2.7/site-packages/invenio_oauthclient/contrib/cern.py", line 218, in account_groups
    groups = fetch_groups(resource['Group'])
KeyError: 'Group'

There is a problem with CERN Oauth as the Groups are not returned in resource. The problem comes from CERN Oauth service. Anyone experiencing the same issue ? Any workaround on this?

CERN: CFG_EXTERNAL_AUTH_HIDDEN_GROUPS* config options renaming

Rename configuration options starting with CFG_* to follow Invenio 3 naming style:

  1. OAUTHCLIENT_CERN_HIDDEN_GROUPS* - fits the module naming
  2. CERN_HIDDEN_GROUPS* - just shorter version that fits the name in contrib folder

cc @inveniosoftware/triagers
addresses #73

global: move oauthclient into new module structure

  • Bootstrap module with cookiecutter template.
  • Registries -> entry points + register function on extension
  • Create extension class
  • Config (see example from Invenio-Records)
  • ... (e.g. Flask-BabelEx for gettext/_, User from invenio-accounts)
    • mark all user facing strings in templates with {{ _(...) }}
    • update catalog (pot)
  • Fix imports
  • Dependencies in setup.py
  • Extension + Blueprints in setup.py
  • Find solution UserExt/UserInfo
  • Load blueprints via entry point
  • Settings module (see invenio-accounts/userprofiles)
  • Minimal example app
  • Python 3 support
  • Templates: Move away from base template - see invenio-theme
  • Test: test cover 90%+
  • upgrade flask-oauthlib version.
  • remove deprecated code

global: urldecoding

  • oauthlib have strict decode
  • invenio-oauh2server allows you to override that strict configuration
  1. Check if invenio-search-js is properly sending fully encoding URL strings so that we don't get internal server errors.

cern: lightweight account throws 500

This change has introduced a bug for lightweight accounts. CERN lightweight accounts do not have have a uidNumber, so when logging in you get a stack trace on external_id:

KeyError: 'uidNumber'

invenio_oauthclient/contrib/cern.py in account_info at line 262
def account_info(remote, resp):
    """Retrieve remote account information used to find local user."""
    resource = get_resource(remote)
    email = resource['EmailAddress'][0]
    external_id = resource['uidNumber'][0]
Click to see an example of a login with a lightweight CERN account

``` [ { "Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "Value": "@gmail.com" }, { "Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", "Value": "@gmail.com" }, { "Type": "http://schemas.xmlsoap.org/claims/UPN", "Value": "@gmail.com" }, { "Type": "http://schemas.xmlsoap.org/claims/EmailAddress", "Value": "@gmail.com" }, { "Type": "http://schemas.xmlsoap.org/claims/CommonName", "Value": "j34hwtjhtg54g64j646g4" }, { "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "Value": "CERN Externals" }, { "Type": "http://schemas.xmlsoap.org/claims/DisplayName", "Value": "@gmail.com" }, { "Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Value": "@gmail.com" }, { "Type": "http://schemas.xmlsoap.org/claims/PersonID", "Value": "-3243534" }, { "Type": "http://schemas.xmlsoap.org/claims/IdentityClass", "Value": "Unverified External" }, { "Type": "http://schemas.xmlsoap.org/claims/Federation", "Value": "CERN" }, { "Type": "http://schemas.xmlsoap.org/claims/AuthLevel", "Value": "Normal" }, { "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "Value": "http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password" }, { "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant", "Value": "2018-10-19T13:53:34.834Z" }, { "Type": "urn:oauth:scope", "Value": "all" }, { "Type": "http://schemas.xmlsoap.org/claims/Group", "Value": "All Exchange People" } ] ```

Click to see an example of a login with a normal CERN account

``` [ { "Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "Value": "@cern.ch" }, { "Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", "Value": "@cern.ch" }, { "Type": "http://schemas.xmlsoap.org/claims/UPN", "Value": "@cern.ch" }, { "Type": "http://schemas.xmlsoap.org/claims/EmailAddress", "Value": "@cern.ch" }, { "Type": "http://schemas.xmlsoap.org/claims/CommonName", "Value": "" }, { "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "Value": "CERN Users" }, { "Type": "http://schemas.xmlsoap.org/claims/DisplayName", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/Building", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/Firstname", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/Lastname", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/Department", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/HomeInstitute", "Value": "CERN" }, { "Type": "http://schemas.xmlsoap.org/claims/PersonID", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/uidNumber", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/gidNumber", "Value": "" }, { "Type": "http://schemas.xmlsoap.org/claims/PreferredLanguage", "Value": "EN" }, { "Type": "http://schemas.xmlsoap.org/claims/IdentityClass", "Value": "CERN Registered" }, { "Type": "http://schemas.xmlsoap.org/claims/Federation", "Value": "CERN" }, { "Type": "http://schemas.xmlsoap.org/claims/AuthLevel", "Value": "Normal" }, { "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "Value": "http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password" }, { "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant", "Value": "2018-10-19T12:41:25.214Z" }, { "Type": "urn:oauth:scope", "Value": "all" }, { "Type": "http://schemas.xmlsoap.org/claims/Group", "Value": "All Exchange People" }, ... List of e-groups here ... ] ```

This is causing a 500 Internal Server Error.

global: configurable OAuthRemoteApp factory

Problem:
Some OAuth services like B2Access (which uses Unity) or reddit require the use of Basic HTTP authentication when retrieving the access token.
Flask-OAuthlib provides an example as to how to handle this specific use-case. It requires a subclass of OAuthRemoteApp.

The problem is that there is currently no way to provide a custom OAuthRemoteApp to invenio-oauthclient. The extension creates clients by calling flask-oauth or flask-oauthlib remote_app method.

Suggested solution:
Create a config variable which would default to the current behavior, but also enables the replacement of self.oauth.remote_app with a custom factory.

Who needs it:
B2Share in order to use B2Access OAuth service.

admin: add user_identity view and changes names

  • Add an admin view for the UserIdentity model.
  • Change admin view name from Remote Accounts -> Linked accounts
  • Change admin view name from Remote Tokens -> Linked account tokens
  • Change admin view name from UserIdentity -> Linked account identities

See example of changing name in Access

cern: PersonID is not an unique identifier

To recognize CERN user, field PersonID is used (as an external id). This field is the same for all accounts associated with the same user (primary, secondary and service accounts).
Field uidNumber can be used instead.

global: auto-registration is broken

When user is not found on the db, we automatically register them with password=None, as seen here: https://github.com/inveniosoftware/invenio-oauthclient/blob/master/invenio_oauthclient/utils.py#L92-L103

But Passlib does not allow None passwords, although it allows empty ones (''). To verify it, run:

>>> from passlib.hash import oracle10
>>> hash = oracle10.encrypt(None, user='admin')
>>> hash = oracle10.encrypt('', user='admin')

Therefore, if the user is not already registered, an internal server error will occur.

tests: simplify doctest execution

The following cookiecutter change:

inveniosoftware/cookiecutter-invenio-module#98

should be propagated to this Invenio module.

Namely, in run-tests.sh, the sphinx for doctests is invoked after pytest run:

$ tail -3 ./\{\{\ cookiecutter.project_shortname\ \}\}/run-tests.sh
sphinx-build -qnNW docs docs/_build/html && python setup.py test && sphinx-build -qnNW -b doctest docs docs/_build/doctest

This sometimes led to problems on Travis CI with the second sphinx-build run due
to "disappearing" dependencies after the example application was tested.

A solution that worked for invenio-marc21 (see
inveniosoftware/invenio-marc21#49 (comment))
and that was integrated in cookiecutter (see
inveniosoftware/cookiecutter-invenio-module#98) was to
run doctest execution in pytest, removing the second sphinx-build invocation.

This both solved Travis CI build failures and simplified test suite execution.

Note that this change may necessitate to amend the code tests etc so that things
would be executed with the Flask application context (see
inveniosoftware/invenio-marc21@09e98fc).

global: make a better separation between request-related and "business logic" code

The various client handlers contain business logic related to how to e.g. disconnect a user from an OAuth service which shouldn't depend on the request context. Example from invenio_oauthclient.contrib.orcid.disconnect_handler:

...
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account.
    :param remote: The remote application.
    """
    # ...this is request-related...
    if not current_user.is_authenticated: 
        return current_app.login_manager.unauthorized()

    # -- START --
    # This part should be in a different function, since it only depends on a User ID
    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()
    # -- END --

    # ...this is request-related...
    return redirect(url_for('invenio_oauthclient_settings.index'))
...

cern: user login with "access_token" not working

When you try to do a call through the API and using the access_token an error is thrown,
since it tries to get resources that are not there. This is due to token expiration from CERN oAuth (works when you login through the browser, and try the access_token first minutes before expiration).

We need to create a "refresh_token" mechanism for this to get fixed or find another workaround like storing "Groups" in the extra_data field (not ideal since User might be removed from a group and it won't get synced with our instance)

Related with #68

  File "/Users/p/.envs/cap/lib/python2.7/site-packages/invenio_oauth2server/ext.py", line 201, in verify_oauth_token_and_set_current_user
    valid, req = func(valid, req)
  File "/Users/p/.envs/cap/src/analysispreservation.cern.ch/cap/modules/oauth2server/views/server.py", line 57, in login_oauth2_user
    identity=Identity(oauth.user.id))
  File "/Users/p/.envs/cap/lib/python2.7/site-packages/blinker/base.py", line 267, in send
    for receiver in self.receivers_for(sender)]
  File "/Users/p/.envs/cap/lib/python2.7/site-packages/invenio_oauthclient/contrib/cern.py", line 357, in on_identity_changed
    account_groups(account, resource, refresh_timedelta=refresh)
  File "/Users/p/.envs/cap/lib/python2.7/site-packages/invenio_oauthclient/contrib/cern.py", line 224, in account_groups
    groups = fetch_groups(resource['Group'])
KeyError: 'Group'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.