inveniosoftware / invenio-oauthclient Goto Github PK
View Code? Open in Web Editor NEWInvenio module that provides OAuth web authorization support.
Home Page: https://invenio-oauthclient.readthedocs.io
License: MIT License
Invenio module that provides OAuth web authorization support.
Home Page: https://invenio-oauthclient.readthedocs.io
License: MIT License
UserIdentity
model.Remote Accounts -> Linked accounts
Remote Tokens -> Linked account tokens
UserIdentity -> Linked account identities
See example of changing name in Access
gettext/_
, User from invenio-accounts)
{{ _(...) }}
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.
The package contains examples/app.py
example application, but there is no test
for it in tests/test_example_app.py
. It should be added. See existing examples:
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.
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'
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?
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.
This module is currently used in B2Share. As B2Share does not use the Flask UI provided by Invenio, it loads invenio-oauthclient
in its api.
The steps explaining how to use invenio-oauthclient
in an API application need to be documented.
As you can see here: https://travis-ci.org/inveniosoftware/invenio-oauthclient/builds/158729080
There is a issue with lowest requirements and python 2.7.
CDefError: 'point_conversion_form_t' has no values explicitly defined: refusing to guess which integer type it is meant to be (unsigned/signed, int/long)
I think I found the problem and I'll make a PR.
This error occurs when logging in via cern.
It is caused when this method is called:
https://github.com/inveniosoftware/invenio-oauthclient/blob/master/invenio_oauthclient/contrib/cern.py#L236
To reproduce it Sign in, Sign out and then again sign in and the error should appear.
A remote app cannot set remember=True
since the parameter is ignored (
The parameter should be passed to login_user
instead.
"Advanced" section in docs have no text:
http://invenio-oauthclient.readthedocs.io/en/latest/usage.html#module-invenio_oauthclient
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?
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).
@lnielsen commented on Mon Aug 18 2014
RemoteToken
model.Reproduce:
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': '{}'}]
It looks like the registration for is not correctly populated.
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)
Next URL problem? Demosite, does it work that you are not redirected to linked account menu bullet?
Put extra information as given_names
and family_name
in invenio-userprofiles
.
Seems related to SQLAlchemy-Continuum
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.
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.
Unpin HTTPretty version once version 0.8.13 is out. See gabrielfalcao/HTTPretty#277
Rename configuration options starting with CFG_*
to follow Invenio 3 naming style:
OAUTHCLIENT_CERN_HIDDEN_GROUPS*
- fits the module namingCERN_HIDDEN_GROUPS*
- just shorter version that fits the name in contrib
foldercc @inveniosoftware/triagers
addresses #73
param
, returns
, raises
, versionadded
)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]
``` [ { "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" } ] ```
``` [ { "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.
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.
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'))
...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.