Open aestoltm opened 2 years ago
Would you consider Django Social Auth for providing orcid-cf coupling? I could provided sample config. It provides proper SSO/Oauth exchange and user need to login to orcid as 'proof of ownership'.
And from our expirience: be aware that orcid records dont always have full structure
czw., 21 lip 2022, 22:38 użytkownik aestoltm @.***> napisał:
Draft PR that is built off PR (#359 https://github.com/ubccr/coldfront/pull/359) created by @RyanChang0369 https://github.com/RyanChang0369.
Current Bugs:
- UI bug on add publication page showing 'import grants from user ORCID' instead of 'import publications from user ORCID'
- Sometimes grants added through ORCID are skipped and are not presented on the project detail page. (could be the same case for publications)
Current Enchantments:
- Added user's name next to ORCID when performing ORCID search for pulling publications and grants
More bugs or enchantments may be added as further testing is performed.
You can view, comment on, or merge this pull request online at:
https://github.com/ubccr/coldfront/pull/437 Commit Summary
- 224271a https://github.com/ubccr/coldfront/pull/437/commits/224271a53db11653e0ac17b40b69b48756f4c5ca Merge 1: Minor bug fixes and attempt 1 to reduce size of PR
- 9e7971e https://github.com/ubccr/coldfront/pull/437/commits/9e7971e06bcaa42b7c2b8971dad5249f94c4d22c Update/merge ORCID functionality with new commits
- 34f2204 https://github.com/ubccr/coldfront/pull/437/commits/34f22047aedbb7dd23585a407689b6439c1ceab4 Added ORCID field to user profile.
- 583e5a2 https://github.com/ubccr/coldfront/pull/437/commits/583e5a2d25ec67eedfcfa4668dd19e875c403434 Added support for direct ORCID import
- 075c71e https://github.com/ubccr/coldfront/pull/437/commits/075c71e8db8abb511179f9ca3530d358ff0b0b91 Added user ORCID import for grants.
- 0d28fff https://github.com/ubccr/coldfront/pull/437/commits/0d28fffa3b1338eb1cf9d787bb08391dcd84d10f Updated ORCID input fields. Now can paste
- 9d4e84e https://github.com/ubccr/coldfront/pull/437/commits/9d4e84e9a85be7c635eea682892dde8e0cc9fd31 Bug fix: Updating user profile as another user
- 8941d34 https://github.com/ubccr/coldfront/pull/437/commits/8941d348b7debbdc5f7f928f697c7b688f7ed4ca Removed user selection before using user ORCIDs
- a296d27 https://github.com/ubccr/coldfront/pull/437/commits/a296d275ca7571db4724e8b38b9640461058cbd7 Removed unused form
- 6412e1e https://github.com/ubccr/coldfront/pull/437/commits/6412e1e29367b31bbed753acdb481a78640c2640 Changed formatting of orcid input on user profile.
- fd7fc25 https://github.com/ubccr/coldfront/pull/437/commits/fd7fc252994431cf7aff11fc7464c9c01b66e3d8 ORCID implementation PR rebase
File Changes
(33 files https://github.com/ubccr/coldfront/pull/437/files)
- M coldfront/core/grant/admin.py https://github.com/ubccr/coldfront/pull/437/files#diff-7953ae83273c2cdf73bb808da48344011164a35f7b17da428835af8464ef8aa5 (5)
- M coldfront/core/grant/forms.py https://github.com/ubccr/coldfront/pull/437/files#diff-a8ed7c3cf6f1c7e1b250209ec49664572fa378c8c03e2ea3f489c656425585e1 (28)
- A coldfront/core/grant/migrations/0002_grantsource_grantstaged.py https://github.com/ubccr/coldfront/pull/437/files#diff-b8ce3c726c4b1074115506f82047fc473ce6fc4ff410049b89f4b1ae7749ed07 (51)
- M coldfront/core/grant/models.py https://github.com/ubccr/coldfront/pull/437/files#diff-7bb34ce207e4baf723ab8be4d9dbc0b4b9c796eff5c4d1e99146b2b9cc2bbb98 (51)
- M coldfront/core/grant/templates/grant/grant_create.html https://github.com/ubccr/coldfront/pull/437/files#diff-e4eb57acf0947b8e290fe7b6248508df3976447e0eeab9e7ba72edec428df1d7 (27)
- A coldfront/core/grant/templates/grant/grant_orcid_import.html https://github.com/ubccr/coldfront/pull/437/files#diff-fbcd4a325bc4a9a1fc6bbc62cdc0a38bd74511407c7b2ca07406e69e5e95469f (85)
- A coldfront/core/grant/templates/grant/grant_orcid_import_search_result.html https://github.com/ubccr/coldfront/pull/437/files#diff-796a7c30e240c275981119bb154ce76cf22b9da9e5e9cc574185944bb52245c3 (156)
- M coldfront/core/grant/urls.py https://github.com/ubccr/coldfront/pull/437/files#diff-1149cd9e5743db8e58cb37617a386274fd96755ee082a06c4d9d5726a8064e84 (3)
- M coldfront/core/grant/views.py https://github.com/ubccr/coldfront/pull/437/files#diff-41b30c6db70ae9dc9f06c1714de3bc94afc734ed95bc5f07bb08be2fe4fbfb67 (414)
- M coldfront/core/publication/forms.py https://github.com/ubccr/coldfront/pull/437/files#diff-85e51240dd3493b9072fd5cdec9b1ea762d4056ea4621723005144626c403687 (12)
- M coldfront/core/publication/management/commands/add_default_publication_sources.py https://github.com/ubccr/coldfront/pull/437/files#diff-d2942d464b21af1f7fb9a2f1b604ae246885ebe5cf4beb706b5cdb12a9e84ae9 (1)
- A coldfront/core/publication/migrations/0005_auto_20220526_1058.py https://github.com/ubccr/coldfront/pull/437/files#diff-daa487ce3c8fd378a6d1fa404cbf181714645b1756e78ad4407de145cf532f21 (23)
- M coldfront/core/publication/models.py https://github.com/ubccr/coldfront/pull/437/files#diff-7cd7426967bf993e869e7ce657a4ba94a8791e78a060e96e4dfb02aabb7e7872 (1)
- M coldfront/core/publication/templates/publication/publication_add_publication_search.html https://github.com/ubccr/coldfront/pull/437/files#diff-7cccd17839cc4364e4121eecc02b4b5a5f09a84705c4c4790c3b72c36b1105b7 (18)
- M coldfront/core/publication/templates/publication/publication_add_publication_search_result.html https://github.com/ubccr/coldfront/pull/437/files#diff-1952d63894d9344466bc6f99ae25e7e0c1da86f18983e0193cdf678bafdf23c8 (55)
- M coldfront/core/publication/templates/publication/publication_delete_publications.html https://github.com/ubccr/coldfront/pull/437/files#diff-5b69820ef24de0b9fddbbd0c371ad00a023307c5aa5f3914c006be1fa7fef6a0 (22)
- M coldfront/core/publication/urls.py https://github.com/ubccr/coldfront/pull/437/files#diff-385acb6c72481157cf3f3405a9e2841af91bcfc63f13f084d5a1f6c65253d7b3 (1)
- M coldfront/core/publication/views.py https://github.com/ubccr/coldfront/pull/437/files#diff-38504e8009a2b9b94408229f41d21b4bca5b487d0c01f18d529aeb96c0f788a3 (298)
- M coldfront/core/user/forms.py https://github.com/ubccr/coldfront/pull/437/files#diff-f26fbf6bd3527b14da77035b8f6c263fa6ba15cb5ea48cf6403c9ec1b481ba40 (28)
- A coldfront/core/user/migrations/0002_userprofile_orcid_id.py https://github.com/ubccr/coldfront/pull/437/files#diff-b325ddfb1650945fdf43b58c7da57ff39ce6a6e9e88b331cd328815ffe287449 (18)
- A coldfront/core/user/migrations/0003_alter_userprofile_orcid_id.py https://github.com/ubccr/coldfront/pull/437/files#diff-f2aaac631523e8a6ee2eb3f8440e106ffb391624e58dfe5c974b6108d4469573 (18)
- A coldfront/core/user/migrations/0004_alter_userprofile_orcid_id.py https://github.com/ubccr/coldfront/pull/437/files#diff-c42bbcd96e129d3185ba3c98c0c81098f68fcc589538bc1864109b12678c5af6 (19)
- M coldfront/core/user/models.py https://github.com/ubccr/coldfront/pull/437/files#diff-5035378c16ed22e52e73a98f3470fdeab414e9f81c17b9ee05340ae79b4cc8ba (72)
- M coldfront/core/user/templates/user/user_profile.html https://github.com/ubccr/coldfront/pull/437/files#diff-8bbdb3987c81731c1694ef0562727352fa9092771865e63d382b8c7998be91dd (11)
- A coldfront/core/user/templates/user/user_select_home.html https://github.com/ubccr/coldfront/pull/437/files#diff-31006431bfb65f2b82283b646b153c281468290330dcf9171f31853675adb16e (84)
- A coldfront/core/user/templates/user/user_select_results.html https://github.com/ubccr/coldfront/pull/437/files#diff-0311422d2d609be5e1563c72c9cac1125a140217a5d542e62e85ca93ca010e74 (59)
- M coldfront/core/user/urls.py https://github.com/ubccr/coldfront/pull/437/files#diff-0cf816601bbc277722d6d0992e40816aa1fff983ca79367e191503f9c9009774 (6)
- M coldfront/core/user/views.py https://github.com/ubccr/coldfront/pull/437/files#diff-13fd4e77677d355fbb7113775996ac3f8d1846ee09b17baff1a72cbd4d3a2478 (168)
- A coldfront/dict_methods.py https://github.com/ubccr/coldfront/pull/437/files#diff-0da7ab25e367215a77afd4341d949129086da50bf00fd394b8c6e38e5c0c515b (24)
- A coldfront/orcid_vars.py https://github.com/ubccr/coldfront/pull/437/files#diff-29002419ad56102327449cd14892289f03e3873019c52b3cc8256ac0f11078ea (47)
- M coldfront/static/common/css/common.css https://github.com/ubccr/coldfront/pull/437/files#diff-66f34131a6a935e1b3cf0b8b611d737037d492d42052ddc62c7643b392950a8c (10)
- M requirements.txt https://github.com/ubccr/coldfront/pull/437/files#diff-4d7c51b1efe9043e44439a949dfd92e5827321b34082903477fd04876edb7552 (1)
- M setup.py https://github.com/ubccr/coldfront/pull/437/files#diff-60f61ab7a8d1910d86d9fda2261620314edcae5894d5aaa236b821c7256badd7 (1)
Patch Links:
— Reply to this email directly, view it on GitHub https://github.com/ubccr/coldfront/pull/437, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA3A5RZHFWWINT2HTLE6Y7TVVGRJ7ANCNFSM54IYYTZA . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Would you consider Django Social Auth for providing orcid-cf coupling? I could provided sample config.
Yes absolutely. We'll be making some more changes/fixes to this PR before it gets merged so happy to take any suggestions on how to improve. A sample config would be great.
@mdzik For the usage of Django Social Auth, are you using the library django-social-auth (https://github.com/omab/django-social-auth) which is dependent on python-social-auth (https://github.com/omab/python-social-auth)? These libraries are deprecated and I was wondering if you were using the updated version, social-app-django (https://github.com/python-social-auth/social-app-django) which is dependent on social-core (https://github.com/python-social-auth/social-core).
@aestoltm - sorry for long reply, :palm_tree:
You are obviously right - we use social-core and social-app-django.
our social pipeline looks like that:
#------------------------------------------------------------------------------
# Authentication backends
#------------------------------------------------------------------------------
AUTHENTICATION_BACKENDS = [
'coldfront.plugins.social_auth.dispatcher_backend.DispatcherBackend'
]
SOCIAL_AUTH_PIPELINE = (
# 'social_core.pipeline.debug.debug',
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.social_user',
'coldfront.plugins.social_auth.restrict_to_existing.validate_user',
#'social_core.pipeline.user.get_username',
#'social_core.pipeline.social_auth.associate_by_email', DONT
#'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
#'social_core.pipeline.user.user_details', Update user model attributes with the new data sent by the current provider
)
AUTHENTICATION_BACKENDS += ['social_core.backends.orcid.ORCIDOAuth2']
AUTHENTICATION_BACKENDS += ['social_core.backends.keycloak.KeycloakOAuth2']
#Those might be needed for Keycloak/ORCID to work, depending on reverse-proxy configuration
SOCIAL_AUTH_VERIFY_SSL = False
SESSION_COOKIE_SECURE = True
SOCIAL_AUTH_REDIRECT_IS_HTTPS = True
USE_X_FORWARDED_HOST = True
We use 2 social providers: ORCID and our Keykloak IDP. Users could bind account to ORCID, but login is limited to Keycloak. Some subset of our PI's don't have LDAP/Keycloak account, so we permit those accounts to login using Django model auth. They have @ in username
And the coldfront.plugins.social_auth.restrict_to_existing file:
from social_core.exceptions import AuthForbidden
from social_core.backends.keycloak import KeycloakOAuth2
from django.contrib.auth.models import User
from pprint import pprint
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import redirect
from django.contrib.auth.models import User
from social_core.pipeline.partial import partial
@partial
def validate_user(strategy, user=None, **kwargs):
if user is None:
if isinstance(kwargs['backend'], KeycloakOAuth2):
try:
user = User.objects.get(username=kwargs['response']['preferred_username'])
except ObjectDoesNotExist:
raise AuthForbidden(strategy)
if not (str(kwargs['response']['preferred_username']) == user.username): # just in case
raise AuthForbidden(strategy)
return {'user': user,
'is_new': False
}
else:
raise AuthForbidden(strategy)
return
coldfront.plugins.social_auth.dispatcher_backend.DispatcherBackend
from django.contrib.auth.backends import ModelBackend
from django.contrib import messages
from django.utils.translation import gettext as _
from django.http import Http404
class DispatcherBackend(ModelBackend):
def authenticate(self, request, username=None, password=None):
if '@' not in username:
messages.error(request, _('All ICM users are required to login using IDP, and provide their MFA password.'))
raise Http404("Authentication method not avalible!")
return None
return super().authenticate(request, username, password)
To extract user data from ORCID API we use:
user = viewed_user
context['has_orcid'] = False
context['has_orcid_employments'] = False
if user.social_auth.exists():
try:
social = user.social_auth.get(provider='orcid')
api = orcid.PublicAPI(SOCIAL_AUTH_ORCID_KEY, SOCIAL_AUTH_ORCID_SECRET)
employments = api.read_record_public(social.extra_data['id'], 'employments', social.extra_data['access_token'])
base_orcid = api.read_record_public(social.extra_data['id'], 'record', social.extra_data['access_token'])
context['has_orcid'] = True
context['ORCID_url'] = base_orcid['orcid-identifier']['uri']
context['ORCID'] = base_orcid['orcid-identifier']['uri']
if 'employment-summary' in employments.keys() and len(employments['employment-summary']) > 0:
context['has_orcid_employments'] = True
context['ORCID_empoyments'] = employments['employment-summary']
This way you could get 'institutional token' from ORCID, and have broader access to user data - as the geve a consent to you while logging. I must admit that I did not tested that - to much paperwork ;)
2. Sometimes grants added through ORCID are skipped and are not presented on the project detail page. (could be the same case for publications) [NOTE: Skips grants with no grant number so might not be a bug. Every grant should have a grant number associated with it.]
ORCID data have 'holes'. I think they do not force most of the fields during input. Even some publications don't have full 'basic' info, including authors :/ It;s not frequent, but annoying. I try to always assume that any given element of ORCID tree could be missing.
@mdzik Thank you for providing sample usage of social-core and social-app-django! We appreciate the information you provided to help us better configure these libraries for our OAuth needs. We will make sure to keep in mind that ORCID records are not complete for when we pull user data.
Additional changes to be made to the general 'Add Publication' and 'Add Grant' workflow that came out of this feature:
On the 'Add Publication' page:
On the 'Add Grant' page:
Draft PR that is built off PR (#359) created by @RyanChang0369.
Current Bugs:
Current Enchantments:
More bugs or enchantments may be added as further testing is performed.