From 90436b635905a94564dfc93c76c1debfc7df5cbd Mon Sep 17 00:00:00 2001 From: abram axel booth Date: Thu, 31 Oct 2024 14:32:05 -0400 Subject: [PATCH] fix: two few adapters --- osf_oauth2_adapter/adapters.py | 33 ++++++++++++++++ osf_oauth2_adapter/provider.py | 5 ++- osf_oauth2_adapter/views.py | 72 +++------------------------------- project/settings.py | 2 +- 4 files changed, 44 insertions(+), 68 deletions(-) create mode 100644 osf_oauth2_adapter/adapters.py diff --git a/osf_oauth2_adapter/adapters.py b/osf_oauth2_adapter/adapters.py new file mode 100644 index 000000000..383b5ff4d --- /dev/null +++ b/osf_oauth2_adapter/adapters.py @@ -0,0 +1,33 @@ +import requests + +from allauth.socialaccount.adapter import DefaultSocialAccountAdapter +from allauth.socialaccount.providers.oauth2.views import OAuth2Adapter + +from .apps import OsfOauth2AdapterConfig + + +class OSFSocialAccountAdapter(DefaultSocialAccountAdapter): + def populate_user(self, request, sociallogin, data): + # super-method populates username, first_name, last_name, email + user = super().populate_user(request, sociallogin, data) + user.time_zone = data.get('time_zone') + user.locale = data.get('locale') + user.gravatar = data.get('profile_image_url') + return user + + +class OSFOAuth2Adapter(OAuth2Adapter): + provider_id = 'osf' + base_url = '{}oauth2/{}'.format(OsfOauth2AdapterConfig.osf_accounts_url, '{}') + access_token_url = base_url.format('token') + authorize_url = base_url.format('authorize') + profile_url = '{}v2/users/me/'.format(OsfOauth2AdapterConfig.osf_api_url) + + def complete_login(self, request, app, access_token, **kwargs): + extra_data = requests.get(self.profile_url, headers={ + 'Authorization': 'Bearer {}'.format(access_token.token) + }) + return self.get_provider().sociallogin_from_response( + request, + extra_data.json() + ) diff --git a/osf_oauth2_adapter/provider.py b/osf_oauth2_adapter/provider.py index 4b1681c92..6999a7072 100644 --- a/osf_oauth2_adapter/provider.py +++ b/osf_oauth2_adapter/provider.py @@ -1,7 +1,9 @@ -from .apps import OsfOauth2AdapterConfig from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider +from .apps import OsfOauth2AdapterConfig +from .adapters import OSFOAuth2Adapter + class OSFAccount(ProviderAccount): def to_str(self): @@ -26,6 +28,7 @@ class OSFProvider(OAuth2Provider): id = 'osf' name = 'Open Science Framework' account_class = OSFAccount + oauth2_adapter_class = OSFOAuth2Adapter def extract_common_fields(self, data): attributes = data.get('data').get('attributes') diff --git a/osf_oauth2_adapter/views.py b/osf_oauth2_adapter/views.py index 654a9461f..0b3f9f4bc 100644 --- a/osf_oauth2_adapter/views.py +++ b/osf_oauth2_adapter/views.py @@ -1,71 +1,7 @@ -import requests - +from allauth.socialaccount.providers.oauth2.views import OAuth2LoginView, OAuth2CallbackView from django.views.generic.base import TemplateView -from allauth.socialaccount.adapter import DefaultSocialAccountAdapter - -from allauth.utils import valid_email_or_none - -from allauth.account.utils import user_email, user_username, user_field - -from .apps import OsfOauth2AdapterConfig -from allauth.socialaccount.providers.oauth2.views import OAuth2Adapter, OAuth2LoginView, OAuth2CallbackView - -from osf_oauth2_adapter.provider import OSFProvider - - -class OSFOAuth2Adapter(OAuth2Adapter, DefaultSocialAccountAdapter): - provider_id = OSFProvider.id - base_url = '{}oauth2/{}'.format(OsfOauth2AdapterConfig.osf_accounts_url, '{}') - access_token_url = base_url.format('token') - authorize_url = base_url.format('authorize') - profile_url = '{}v2/users/me/'.format(OsfOauth2AdapterConfig.osf_api_url) - - def populate_user(self, request, sociallogin, data): - """ - Hook that can be used to further populate the user instance. - - For convenience, we populate several common fields. - - Note that the user instance being populated represents a - suggested User instance that represents the social user that is - in the process of being logged in. - - The User instance need not be completely valid and conflict - free. For example, verifying whether or not the username - already exists, is not a responsibility. - """ - username = data.get('username') - first_name = data.get('first_name') - last_name = data.get('last_name') - email = data.get('email') - name = data.get('name') - time_zone = data.get('time_zone') - locale = data.get('locale') - gravatar = data.get('profile_image_url') - user = sociallogin.user - user_username(user, username or '') - user_email(user, valid_email_or_none(email) or '') - name_parts = (name or '').partition(' ') - user_field(user, 'first_name', first_name or name_parts[0]) - user_field(user, 'last_name', last_name or name_parts[2]) - user_field(user, 'time_zone', time_zone) - user_field(user, 'locale', locale) - user_field(user, 'gravatar', gravatar) - return user - - def complete_login(self, request, app, access_token, **kwargs): - extra_data = requests.get(self.profile_url, headers={ - 'Authorization': 'Bearer {}'.format(access_token.token) - }) - return self.get_provider().sociallogin_from_response( - request, - extra_data.json() - ) - - -oauth2_login = OAuth2LoginView.adapter_view(OSFOAuth2Adapter) -oauth2_callback = OAuth2CallbackView.adapter_view(OSFOAuth2Adapter) +from .adapters import OSFOAuth2Adapter class LoginErroredCancelledView(TemplateView): @@ -73,3 +9,7 @@ class LoginErroredCancelledView(TemplateView): login_errored_cancelled = LoginErroredCancelledView.as_view() + +# used by allauth.socialaccount.providers.oauth2.urls.default_urlpatterns +oauth2_login = OAuth2LoginView.adapter_view(OSFOAuth2Adapter) +oauth2_callback = OAuth2CallbackView.adapter_view(OSFOAuth2Adapter) diff --git a/project/settings.py b/project/settings.py index df3a0500b..d091e9e7c 100644 --- a/project/settings.py +++ b/project/settings.py @@ -110,7 +110,7 @@ def split(string, delim): 'approve_changesets': 'Approve ChangeSets' } } -SOCIALACCOUNT_ADAPTER = 'osf_oauth2_adapter.views.OSFOAuth2Adapter' +SOCIALACCOUNT_ADAPTER = 'osf_oauth2_adapter.adapters.OSFSocialAccountAdapter' SOCIALACCOUNT_PROVIDERS = \ {'osf': {