From 57a7bed99dac6a1fe84be8f1a743e5f0f476b6c7 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 25 Jun 2020 10:24:53 +0200 Subject: [PATCH] sources/oauth: fix facebook provider --- Pipfile | 1 + Pipfile.lock | 17 ++++++++++++++++- e2e/utils.py | 2 +- passbook/flows/migrations/0004_source_flows.py | 10 ++++++---- passbook/sources/oauth/forms.py | 6 +++--- passbook/sources/oauth/types/facebook.py | 15 +++++++++++++++ 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Pipfile b/Pipfile index 5f3a4e2d3..cad4fd1b6 100644 --- a/Pipfile +++ b/Pipfile @@ -40,6 +40,7 @@ signxml = "*" structlog = "*" swagger-spec-validator = "*" urllib3 = {extras = ["secure"],version = "*"} +facebook-sdk = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index c6e9ee81b..ecaefd5e2 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e1e229f3276f2f76787b55050506f86e65579bc5aab5c7fca8caa319adb7f3d8" + "sha256": "fd0192b73c01aaffb90716ce7b6d4e5be9adb8788d3ebd58e54ccd6f85d9b71b" }, "pipfile-spec": 6, "requires": { @@ -306,6 +306,14 @@ ], "version": "==1.0.0" }, + "facebook-sdk": { + "hashes": [ + "sha256:2e987b3e0f466a6f4ee77b935eb023dba1384134f004a2af21f1cfff7fe0806e", + "sha256:cabcd2e69ea3d9f042919c99b353df7aa1e2be86d040121f6e9f5e63c1cf0f8d" + ], + "index": "pypi", + "version": "==3.1.0" + }, "future": { "hashes": [ "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" @@ -1189,6 +1197,13 @@ ], "version": "==2020.6.8" }, + "requests": { + "hashes": [ + "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b", + "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898" + ], + "version": "==2.24.0" + }, "selenium": { "hashes": [ "sha256:5f5489a0c5fe2f09cc6bc3f32a0d53441ab36882c987269f2afe805979633ac1", diff --git a/e2e/utils.py b/e2e/utils.py index 68fc787ec..775ce6d44 100644 --- a/e2e/utils.py +++ b/e2e/utils.py @@ -46,7 +46,7 @@ class SeleniumTestCase(StaticLiveServerTestCase): self.driver = self._get_driver() self.driver.maximize_window() self.driver.implicitly_wait(5) - self.wait = WebDriverWait(self.driver, 10) + self.wait = WebDriverWait(self.driver, 60) self.apply_default_data() def _get_driver(self) -> WebDriver: diff --git a/passbook/flows/migrations/0004_source_flows.py b/passbook/flows/migrations/0004_source_flows.py index 9f7e72530..4a2f04432 100644 --- a/passbook/flows/migrations/0004_source_flows.py +++ b/passbook/flows/migrations/0004_source_flows.py @@ -7,10 +7,12 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor from passbook.flows.models import FlowDesignation from passbook.stages.prompt.models import FieldTypes -FLOW_POLICY_EXPRESSION = """return pb_is_sso_flow""" -PROMPT_POLICY_EXPRESSION = ( - """return 'username' in pb_flow_plan.context['prompt_data']""" -) +FLOW_POLICY_EXPRESSION = """# This policy ensures that this flow can only be used when the user +# is in a SSO Flow (meaning they come from an external IdP) +return pb_is_sso_flow""" +PROMPT_POLICY_EXPRESSION = """# Check if we've been given a username by the external IdP +# and trigger the enrollment flow +return 'username' in pb_flow_plan.context.get('prompt_data', {})""" def create_default_source_enrollment_flow( diff --git a/passbook/sources/oauth/forms.py b/passbook/sources/oauth/forms.py index a64c47698..509ace23d 100644 --- a/passbook/sources/oauth/forms.py +++ b/passbook/sources/oauth/forms.py @@ -84,9 +84,9 @@ class FacebookOAuthSourceForm(OAuthSourceForm): overrides = { "provider_type": "facebook", "request_token_url": "", - "authorization_url": "https://www.facebook.com/v2.8/dialog/oauth", - "access_token_url": "https://graph.facebook.com/v2.8/oauth/access_token", - "profile_url": "https://graph.facebook.com/v2.8/me?fields=name,email,short_name", + "authorization_url": "https://www.facebook.com/v7.0/dialog/oauth", + "access_token_url": "https://graph.facebook.com/v7.0/oauth/access_token", + "profile_url": "https://graph.facebook.com/v7.0/me?fields=id,name,email", } diff --git a/passbook/sources/oauth/types/facebook.py b/passbook/sources/oauth/types/facebook.py index 8b20cf3ee..397b4adb0 100644 --- a/passbook/sources/oauth/types/facebook.py +++ b/passbook/sources/oauth/types/facebook.py @@ -1,4 +1,9 @@ """Facebook OAuth Views""" +from typing import Any, Dict, Optional + +from facebook import GraphAPI + +from passbook.sources.oauth.clients import OAuth2Client from passbook.sources.oauth.types.manager import MANAGER, RequestKind from passbook.sources.oauth.utils import user_get_or_create from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect @@ -14,10 +19,20 @@ class FacebookOAuthRedirect(OAuthRedirect): } +class FacebookOAuth2Client(OAuth2Client): + """Facebook OAuth2 Client""" + + def get_profile_info(self, token: Dict[str, str]) -> Optional[Dict[str, Any]]: + api = GraphAPI(access_token=token["access_token"]) + return api.get_object("me", fields="id,name,email") + + @MANAGER.source(kind=RequestKind.callback, name="Facebook") class FacebookOAuth2Callback(OAuthCallback): """Facebook OAuth2 Callback""" + client_class = FacebookOAuth2Client + def get_or_create_user(self, source, access, info): user_data = { "username": info.get("name"),