From 64c47a59f8cc07531d260ec8cdfa4d8d65ca125d Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 9 Jul 2020 00:41:14 +0200 Subject: [PATCH] e2e: add tests for OAuth Source, update tests for new base templates --- e2e/dex/config-dev.yaml | 21 ++ e2e/passbook.side | 498 ------------------------------------ e2e/test_provider_oauth.py | 2 +- e2e/test_provider_oidc.py | 2 +- e2e/test_provider_saml.py | 2 +- e2e/test_source_saml.py | 105 ++++++++ e2e/test_sources_oauth.py | 143 +++++++++++ passbook/policies/mixins.py | 1 + 8 files changed, 273 insertions(+), 501 deletions(-) create mode 100644 e2e/dex/config-dev.yaml delete mode 100644 e2e/passbook.side create mode 100644 e2e/test_sources_oauth.py diff --git a/e2e/dex/config-dev.yaml b/e2e/dex/config-dev.yaml new file mode 100644 index 000000000..6f5304b64 --- /dev/null +++ b/e2e/dex/config-dev.yaml @@ -0,0 +1,21 @@ +enablePasswordDB: true +issuer: http://127.0.0.1:5556/dex +logger: + level: debug +staticClients: +- id: example-app + name: Example App + redirectURIs: + - http://localhost:45713/source/oauth/callback/dex/ + secret: ZXhhbXBsZS1hcHAtc2VjcmV0 +staticPasswords: +- email: admin@example.com + hash: $2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W + userID: 08a8684b-db88-4b73-90a9-3cd1661f5466 + username: admin +storage: + config: + file: /tmp/dex.db + type: sqlite3 +web: + http: 0.0.0.0:5556 diff --git a/e2e/passbook.side b/e2e/passbook.side deleted file mode 100644 index 631e930f8..000000000 --- a/e2e/passbook.side +++ /dev/null @@ -1,498 +0,0 @@ -{ - "id": "7d9b2407-1520-4c04-b040-68e8ada9aecc", - "version": "2.0", - "name": "passbook", - "url": "http://localhost:8000", - "tests": [{ - "id": "94b39863-74ec-4b7d-98c5-2b380b6d2c55", - "name": "passbook login simple", - "commands": [{ - "id": "e60e4382-4f96-44c3-ba06-5e18609c9c2b", - "comment": "", - "command": "open", - "target": "/flows/default-authentication-flow/?next=%2F", - "targets": [], - "value": "" - }, { - "id": "b2652f24-931e-45b0-b01d-2f0ac0f74db8", - "comment": "", - "command": "click", - "target": "id=id_uid_field", - "targets": [ - ["id=id_uid_field", "id"], - ["name=uid_field", "name"], - ["css=#id_uid_field", "css:finder"], - ["xpath=//input[@id='id_uid_field']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "" - }, { - "id": "f1930f8a-984a-4076-a925-20937bb2f8d3", - "comment": "", - "command": "type", - "target": "id=id_uid_field", - "targets": [ - ["id=id_uid_field", "id"], - ["name=uid_field", "name"], - ["css=#id_uid_field", "css:finder"], - ["xpath=//input[@id='id_uid_field']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "admin@example.tld" - }, { - "id": "0b568ee3-1bed-4821-a3bc-f6b960dbed9d", - "comment": "", - "command": "sendKeys", - "target": "id=id_uid_field", - "targets": [ - ["id=id_uid_field", "id"], - ["name=uid_field", "name"], - ["css=#id_uid_field", "css:finder"], - ["xpath=//input[@id='id_uid_field']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "${KEY_ENTER}" - }, { - "id": "6d98e479-2825-484d-996a-ccf350d2761f", - "comment": "", - "command": "type", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "pbadmin" - }, { - "id": "6f7abec6-ff44-4eb5-ae23-520c1c29a706", - "comment": "", - "command": "sendKeys", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "${KEY_ENTER}" - }, { - "id": "04c5876f-1405-4077-a98b-e911f09113d7", - "comment": "", - "command": "assertText", - "target": "xpath=//a[contains(@href, '/-/user/')]", - "targets": [ - ["linkText=pbadmin", "linkText"], - ["css=.pf-c-page__header-tools-group:nth-child(2) > .pf-c-button", "css:finder"], - ["xpath=//a[contains(text(),'pbadmin')]", "xpath:link"], - ["xpath=//div[@id='page-default-nav-example']/header/div[3]/div[2]/a", "xpath:idRelative"], - ["xpath=//a[contains(@href, '/-/user/')]", "xpath:href"], - ["xpath=//div[2]/a", "xpath:position"], - ["xpath=//a[contains(.,'pbadmin')]", "xpath:innerText"] - ], - "value": "pbadmin" - }] - }, { - "id": "61948b3c-3012-4f97-aa52-bc8f34fec333", - "name": "passbook enroll simple", - "commands": [{ - "id": "0f4884b3-4891-41bc-956d-1fa433e892e9", - "comment": "", - "command": "open", - "target": "/flows/default-authentication-flow/?next=%2F", - "targets": [], - "value": "" - }, { - "id": "84d3861f-a60c-4650-8689-535f82b39577", - "comment": "", - "command": "click", - "target": "linkText=Sign up.", - "targets": [ - ["linkText=Sign up.", "linkText"], - ["css=.pf-c-login__main-footer-band-item > a", "css:finder"], - ["xpath=//a[contains(text(),'Sign up.')]", "xpath:link"], - ["xpath=//main[@id='flow-body']/footer/div/p/a", "xpath:idRelative"], - ["xpath=//a[contains(@href, '/flows/default-enrollment-flow/')]", "xpath:href"], - ["xpath=//a", "xpath:position"], - ["xpath=//a[contains(.,'Sign up.')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "a32435ca-d84a-41e7-a915-fcbbc5f88341", - "comment": "", - "command": "type", - "target": "id=id_username", - "targets": [ - ["id=id_username", "id"], - ["name=username", "name"], - ["css=#id_username", "css:finder"], - ["xpath=//input[@id='id_username']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "foo" - }, { - "id": "3b5dcf53-8297-46c5-88b7-11c2eb25f34f", - "comment": "", - "command": "type", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "pbadmin" - }, { - "id": "e948d61c-dae6-4994-b56f-ff130892b342", - "comment": "", - "command": "type", - "target": "id=id_password_repeat", - "targets": [ - ["id=id_password_repeat", "id"], - ["name=password_repeat", "name"], - ["css=#id_password_repeat", "css:finder"], - ["xpath=//input[@id='id_password_repeat']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[3]/input", "xpath:idRelative"], - ["xpath=//div[3]/input", "xpath:position"] - ], - "value": "pbadmin" - }, { - "id": "e7527bfc-ec74-4d96-86f0-5a3a55a59025", - "comment": "", - "command": "click", - "target": "css=.pf-c-button", - "targets": [ - ["css=.pf-c-button", "css:finder"], - ["xpath=//button[@type='submit']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[4]/button", "xpath:idRelative"], - ["xpath=//button", "xpath:position"], - ["xpath=//button[contains(.,'Continue')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "434b842c-a659-4ff5-aca8-06a6a3489597", - "comment": "", - "command": "type", - "target": "id=id_name", - "targets": [ - ["id=id_name", "id"], - ["name=name", "name"], - ["css=#id_name", "css:finder"], - ["xpath=//input[@id='id_name']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "some name" - }, { - "id": "cbc43a1b-2cfe-46e2-85bc-476fb32c6cb1", - "comment": "", - "command": "type", - "target": "id=id_email", - "targets": [ - ["id=id_email", "id"], - ["name=email", "name"], - ["css=#id_email", "css:finder"], - ["xpath=//input[@id='id_email']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "foo@bar.baz" - }, { - "id": "e74389a0-228b-4312-9677-e9add6358de3", - "comment": "", - "command": "click", - "target": "css=.pf-c-button", - "targets": [ - ["css=.pf-c-button", "css:finder"], - ["xpath=//button[@type='submit']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[3]/button", "xpath:idRelative"], - ["xpath=//button", "xpath:position"], - ["xpath=//button[contains(.,'Continue')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "3e22f9c2-5ebd-49c2-81b1-340fa0435bbc", - "comment": "", - "command": "click", - "target": "linkText=foo", - "targets": [ - ["linkText=foo", "linkText"], - ["css=.pf-c-page__header-tools-group:nth-child(2) > .pf-c-button", "css:finder"], - ["xpath=//a[contains(text(),'foo')]", "xpath:link"], - ["xpath=//div[@id='page-default-nav-example']/header/div[3]/div[2]/a", "xpath:idRelative"], - ["xpath=//a[contains(@href, '/-/user/')]", "xpath:href"], - ["xpath=//div[2]/a", "xpath:position"], - ["xpath=//a[contains(.,'foo')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "60124cfd-f11c-4d7f-8b01-bef54c8cbd73", - "comment": "", - "command": "assertText", - "target": "xpath=//a[contains(@href, '/-/user/')]", - "targets": [ - ["linkText=foo", "linkText"], - ["css=.pf-c-page__header-tools-group:nth-child(2) > .pf-c-button", "css:finder"], - ["xpath=//a[contains(text(),'foo')]", "xpath:link"], - ["xpath=//div[@id='page-default-nav-example']/header/div[3]/div[2]/a", "xpath:idRelative"], - ["xpath=//a[contains(@href, '/-/user/')]", "xpath:href"], - ["xpath=//div[2]/a", "xpath:position"], - ["xpath=//a[contains(.,'foo')]", "xpath:innerText"] - ], - "value": "foo" - }, { - "id": "429ee61b-9991-4919-8131-55f8e1bd9a0d", - "comment": "", - "command": "assertValue", - "target": "id=id_username", - "targets": [], - "value": "foo" - }, { - "id": "f6c50760-52ed-4c1d-b232-30f8afe144eb", - "comment": "", - "command": "assertText", - "target": "id=id_name", - "targets": [ - ["id=id_name", "id"], - ["name=name", "name"], - ["css=#id_name", "css:finder"], - ["xpath=//input[@id='id_name']", "xpath:attributes"], - ["xpath=//main[@id='main-content']/section/div/div/div/div[2]/form/div[2]/div/input", "xpath:idRelative"], - ["xpath=//div[2]/div/input", "xpath:position"] - ], - "value": "some name" - }, { - "id": "b26905b5-89b5-4b41-abf5-a9f848f08622", - "comment": "", - "command": "assertText", - "target": "id=id_email", - "targets": [ - ["id=id_email", "id"], - ["name=email", "name"], - ["css=#id_email", "css:finder"], - ["xpath=//input[@id='id_email']", "xpath:attributes"], - ["xpath=//main[@id='main-content']/section/div/div/div/div[2]/form/div[3]/div/input", "xpath:idRelative"], - ["xpath=//div[3]/div/input", "xpath:position"] - ], - "value": "foo@bar.baz" - }] - }, { - "id": "1a3172e0-ac23-4781-9367-19afccee4f4a", - "name": "flows stage setup password", - "commands": [{ - "id": "77784f77-d840-4b3d-a42f-7928f02fb7e1", - "comment": "", - "command": "open", - "target": "/flows/default-authentication-flow/?next=%2F", - "targets": [], - "value": "" - }, { - "id": "783aa9a6-81e5-49c6-8789-2f360a5750b1", - "comment": "", - "command": "setWindowSize", - "target": "1699x1417", - "targets": [], - "value": "" - }, { - "id": "cb0cd63e-30e9-4443-af59-5345fe26dc88", - "comment": "", - "command": "click", - "target": "id=id_uid_field", - "targets": [ - ["id=id_uid_field", "id"], - ["name=uid_field", "name"], - ["css=#id_uid_field", "css:finder"], - ["xpath=//input[@id='id_uid_field']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "" - }, { - "id": "8466ded1-c5f6-451c-b63f-0889da38503a", - "comment": "", - "command": "type", - "target": "id=id_uid_field", - "targets": [ - ["id=id_uid_field", "id"], - ["name=uid_field", "name"], - ["css=#id_uid_field", "css:finder"], - ["xpath=//input[@id='id_uid_field']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "pbadmin" - }, { - "id": "27383093-d01a-4416-8fc6-9caad4926cd3", - "comment": "", - "command": "sendKeys", - "target": "id=id_uid_field", - "targets": [ - ["id=id_uid_field", "id"], - ["name=uid_field", "name"], - ["css=#id_uid_field", "css:finder"], - ["xpath=//input[@id='id_uid_field']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "${KEY_ENTER}" - }, { - "id": "4602745a-0ebb-4425-a841-a1ed4899659d", - "comment": "", - "command": "type", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "pbadmin" - }, { - "id": "d1ff4f81-d8f9-45dc-ad5d-f99b54c0cd18", - "comment": "", - "command": "sendKeys", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "${KEY_ENTER}" - }, { - "id": "014c8f57-7ef2-469c-b700-efa94ba81b66", - "comment": "", - "command": "click", - "target": "css=.pf-c-page__header", - "targets": [ - ["css=.pf-c-page__header", "css:finder"], - ["xpath=//div[@id='page-default-nav-example']/header", "xpath:idRelative"], - ["xpath=//header", "xpath:position"] - ], - "value": "" - }, { - "id": "14e86b6f-6add-4bcc-913a-42b1e7322c79", - "comment": "", - "command": "click", - "target": "linkText=pbadmin", - "targets": [ - ["linkText=pbadmin", "linkText"], - ["css=.pf-c-page__header-tools-group:nth-child(2) > .pf-c-button", "css:finder"], - ["xpath=//a[contains(text(),'pbadmin')]", "xpath:link"], - ["xpath=//div[@id='page-default-nav-example']/header/div[3]/div[2]/a", "xpath:idRelative"], - ["xpath=//a[contains(@href, '/-/user/')]", "xpath:href"], - ["xpath=//div[2]/a", "xpath:position"], - ["xpath=//a[contains(.,'pbadmin')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "8280da13-632e-4cba-9e18-ecae0d57d052", - "comment": "", - "command": "click", - "target": "linkText=Change password", - "targets": [ - ["linkText=Change password", "linkText"], - ["css=.pf-c-nav__section:nth-child(2) .pf-c-nav__link", "css:finder"], - ["xpath=//a[contains(text(),'Change password')]", "xpath:link"], - ["xpath=//nav[@id='page-default-nav-example-primary-nav']/section[2]/ul/li/a", "xpath:idRelative"], - ["xpath=//a[contains(@href, '/-/user/stage/password/b929b529-e384-4409-8d40-ac4a195fcab2/change/?next=%2F-%2Fuser%2F')]", "xpath:href"], - ["xpath=//section[2]/ul/li/a", "xpath:position"], - ["xpath=//a[contains(.,'Change password')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "716d7e0c-79dc-469b-a31f-dceaa0765e9c", - "comment": "", - "command": "click", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "" - }, { - "id": "77005d70-adf0-4add-8329-b092d43f829a", - "comment": "", - "command": "type", - "target": "id=id_password", - "targets": [ - ["id=id_password", "id"], - ["name=password", "name"], - ["css=#id_password", "css:finder"], - ["xpath=//input[@id='id_password']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div/input", "xpath:idRelative"], - ["xpath=//div/input", "xpath:position"] - ], - "value": "test" - }, { - "id": "965ca365-99f4-45d1-97c3-c944269341b9", - "comment": "", - "command": "click", - "target": "id=id_password_repeat", - "targets": [ - ["id=id_password_repeat", "id"], - ["name=password_repeat", "name"], - ["css=#id_password_repeat", "css:finder"], - ["xpath=//input[@id='id_password_repeat']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "" - }, { - "id": "9b421468-c65e-4943-b6b1-1e80410a6b87", - "comment": "", - "command": "type", - "target": "id=id_password_repeat", - "targets": [ - ["id=id_password_repeat", "id"], - ["name=password_repeat", "name"], - ["css=#id_password_repeat", "css:finder"], - ["xpath=//input[@id='id_password_repeat']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[2]/input", "xpath:idRelative"], - ["xpath=//div[2]/input", "xpath:position"] - ], - "value": "test" - }, { - "id": "572c1400-a0f2-499f-808a-18c1f56bf13f", - "comment": "", - "command": "click", - "target": "css=.pf-c-button", - "targets": [ - ["css=.pf-c-button", "css:finder"], - ["xpath=//button[@type='submit']", "xpath:attributes"], - ["xpath=//main[@id='flow-body']/div/form/div[3]/button", "xpath:idRelative"], - ["xpath=//button", "xpath:position"], - ["xpath=//button[contains(.,'Continue')]", "xpath:innerText"] - ], - "value": "" - }] - }], - "suites": [{ - "id": "495657fb-3f5e-4431-877c-4d0b248c0841", - "name": "Default Suite", - "persistSession": false, - "parallel": false, - "timeout": 300, - "tests": ["94b39863-74ec-4b7d-98c5-2b380b6d2c55"] - }], - "urls": ["http://localhost:8000/"], - "plugins": [] -} \ No newline at end of file diff --git a/e2e/test_provider_oauth.py b/e2e/test_provider_oauth.py index 8960ac65d..77fdb4e25 100644 --- a/e2e/test_provider_oauth.py +++ b/e2e/test_provider_oauth.py @@ -230,6 +230,6 @@ class TestProviderOAuth(SeleniumTestCase): self.driver.find_element(By.ID, "id_password").send_keys(Keys.ENTER) self.wait_for_url(self.url("passbook_flows:denied")) self.assertEqual( - self.driver.find_element(By.CSS_SELECTOR, "#flow-body > header > h1").text, + self.driver.find_element(By.CSS_SELECTOR, "header > h1").text, "Permission denied", ) diff --git a/e2e/test_provider_oidc.py b/e2e/test_provider_oidc.py index 1ccdffdbb..7b8b29b22 100644 --- a/e2e/test_provider_oidc.py +++ b/e2e/test_provider_oidc.py @@ -298,6 +298,6 @@ class TestProviderOIDC(SeleniumTestCase): self.driver.find_element(By.ID, "id_password").send_keys(Keys.ENTER) self.wait_for_url(self.url("passbook_flows:denied")) self.assertEqual( - self.driver.find_element(By.CSS_SELECTOR, "#flow-body > header > h1").text, + self.driver.find_element(By.CSS_SELECTOR, "header > h1").text, "Permission denied", ) diff --git a/e2e/test_provider_saml.py b/e2e/test_provider_saml.py index 5187f3849..14cace1ab 100644 --- a/e2e/test_provider_saml.py +++ b/e2e/test_provider_saml.py @@ -211,6 +211,6 @@ class TestProviderSAML(SeleniumTestCase): self.driver.find_element(By.ID, "id_password").send_keys(Keys.ENTER) self.wait_for_url(self.url("passbook_flows:denied")) self.assertEqual( - self.driver.find_element(By.CSS_SELECTOR, "#flow-body > header > h1").text, + self.driver.find_element(By.CSS_SELECTOR, "header > h1").text, "Permission denied", ) diff --git a/e2e/test_source_saml.py b/e2e/test_source_saml.py index 78591d850..599d092a9 100644 --- a/e2e/test_source_saml.py +++ b/e2e/test_source_saml.py @@ -125,3 +125,108 @@ class TestSourceSAML(SeleniumTestCase): self.assertNotEqual( self.driver.find_element(By.ID, "id_username").get_attribute("value"), "" ) + + def test_idp_post(self): + """test SAML Source With post binding""" + sleep(1) + # Bootstrap all needed objects + authentication_flow = Flow.objects.get(slug="default-source-authentication") + enrollment_flow = Flow.objects.get(slug="default-source-enrollment") + keypair = CertificateKeyPair.objects.create( + name="test-idp-cert", certificate_data=IDP_CERT + ) + + SAMLSource.objects.create( + name="saml-idp-test", + slug="saml-idp-test", + authentication_flow=authentication_flow, + enrollment_flow=enrollment_flow, + issuer="entity-id", + sso_url="http://localhost:8080/simplesaml/saml2/idp/SSOService.php", + binding_type=SAMLBindingTypes.POST, + signing_kp=keypair, + ) + + self.driver.get(self.live_server_url) + + self.wait.until( + ec.presence_of_element_located( + (By.CLASS_NAME, "pf-c-login__main-footer-links-item-link") + ) + ) + self.driver.find_element( + By.CLASS_NAME, "pf-c-login__main-footer-links-item-link" + ).click() + self.driver.find_element(By.CSS_SELECTOR, ".pf-c-button").click() + + # Now we should be at the IDP, wait for the username field + self.wait.until(ec.presence_of_element_located((By.ID, "username"))) + self.driver.find_element(By.ID, "username").send_keys("user1") + self.driver.find_element(By.ID, "password").send_keys("user1pass") + self.driver.find_element(By.ID, "password").send_keys(Keys.ENTER) + + # Wait until we're logged in + self.wait.until( + ec.presence_of_element_located( + (By.XPATH, "//a[contains(@href, '/-/user/')]") + ) + ) + self.driver.find_element(By.XPATH, "//a[contains(@href, '/-/user/')]").click() + + # Wait until we've loaded the user info page + self.wait.until(ec.presence_of_element_located((By.ID, "id_username"))) + self.assertNotEqual( + self.driver.find_element(By.ID, "id_username").get_attribute("value"), "" + ) + + def test_idp_post_auto(self): + """test SAML Source With post binding (auto redirect)""" + sleep(1) + # Bootstrap all needed objects + authentication_flow = Flow.objects.get(slug="default-source-authentication") + enrollment_flow = Flow.objects.get(slug="default-source-enrollment") + keypair = CertificateKeyPair.objects.create( + name="test-idp-cert", certificate_data=IDP_CERT + ) + + SAMLSource.objects.create( + name="saml-idp-test", + slug="saml-idp-test", + authentication_flow=authentication_flow, + enrollment_flow=enrollment_flow, + issuer="entity-id", + sso_url="http://localhost:8080/simplesaml/saml2/idp/SSOService.php", + binding_type=SAMLBindingTypes.POST_AUTO, + signing_kp=keypair, + ) + + self.driver.get(self.live_server_url) + + self.wait.until( + ec.presence_of_element_located( + (By.CLASS_NAME, "pf-c-login__main-footer-links-item-link") + ) + ) + self.driver.find_element( + By.CLASS_NAME, "pf-c-login__main-footer-links-item-link" + ).click() + + # Now we should be at the IDP, wait for the username field + self.wait.until(ec.presence_of_element_located((By.ID, "username"))) + self.driver.find_element(By.ID, "username").send_keys("user1") + self.driver.find_element(By.ID, "password").send_keys("user1pass") + self.driver.find_element(By.ID, "password").send_keys(Keys.ENTER) + + # Wait until we're logged in + self.wait.until( + ec.presence_of_element_located( + (By.XPATH, "//a[contains(@href, '/-/user/')]") + ) + ) + self.driver.find_element(By.XPATH, "//a[contains(@href, '/-/user/')]").click() + + # Wait until we've loaded the user info page + self.wait.until(ec.presence_of_element_located((By.ID, "id_username"))) + self.assertNotEqual( + self.driver.find_element(By.ID, "id_username").get_attribute("value"), "" + ) diff --git a/e2e/test_sources_oauth.py b/e2e/test_sources_oauth.py new file mode 100644 index 000000000..1e71b1d45 --- /dev/null +++ b/e2e/test_sources_oauth.py @@ -0,0 +1,143 @@ +"""test OAuth Source""" +from os.path import abspath +from time import sleep + +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.support import expected_conditions as ec +from yaml import safe_dump, safe_load + +from docker import DockerClient, from_env +from docker.models.containers import Container +from docker.types import Healthcheck +from e2e.utils import SeleniumTestCase +from passbook.flows.models import Flow +from passbook.sources.oauth.models import OAuthSource + +TOKEN_URL = "http://127.0.0.1:5556/dex/token" +OAUTH_TEST_SECRET = "ZXhhbXBsZS1hcHAtc2VjcmV0" # noqa + + +class TestSourceOAuth(SeleniumTestCase): + """test OAuth Source flow""" + + container: Container + + def setUp(self): + super().setUp() + self.container = self.setup_client() + + def prepare_dex_config(self): + """Since Dex does not document which environment + variables can be used to configure clients""" + config_file = "./e2e/dex/config-dev.yaml" + with open(config_file, "r+") as _file: + config = safe_load(_file) + config.get("staticClients")[0]["redirectURIs"][0] = self.url( + "passbook_sources_oauth:oauth-client-callback", source_slug="dex" + ) + with open(config_file, "w+") as _file: + safe_dump(config, _file) + + def setup_client(self) -> Container: + """Setup test Dex container""" + self.prepare_dex_config() + client: DockerClient = from_env() + container = client.containers.run( + image="quay.io/dexidp/dex:v2.24.0", + detach=True, + network_mode="host", + auto_remove=True, + command="serve /config.yml", + healthcheck=Healthcheck( + test=["CMD", "wget", "--spider", "http://localhost:5556/dex/healthz"], + interval=5 * 100 * 1000000, + start_period=1 * 100 * 1000000, + ), + volumes={ + abspath("./e2e/dex/config-dev.yaml"): { + "bind": "/config.yml", + "mode": "ro", + } + }, + ) + while True: + container.reload() + status = container.attrs.get("State", {}).get("Health", {}).get("Status") + if status == "healthy": + return container + sleep(1) + + def tearDown(self): + self.container.kill() + super().tearDown() + + def test_oauth_oidc(self): + """test OAuth Source With With OIDC""" + sleep(1) + # Bootstrap all needed objects + authentication_flow = Flow.objects.get(slug="default-source-authentication") + enrollment_flow = Flow.objects.get(slug="default-source-enrollment") + + OAuthSource.objects.create( + name="dex", + slug="dex", + authentication_flow=authentication_flow, + enrollment_flow=enrollment_flow, + provider_type="openid-connect", + authorization_url="http://127.0.0.1:5556/dex/auth", + access_token_url=TOKEN_URL, + profile_url="http://127.0.0.1:5556/dex/userinfo", + consumer_key="example-app", + consumer_secret=OAUTH_TEST_SECRET, + ) + + self.driver.get(self.live_server_url) + + self.wait.until( + ec.presence_of_element_located( + (By.CLASS_NAME, "pf-c-login__main-footer-links-item-link") + ) + ) + self.driver.find_element( + By.CLASS_NAME, "pf-c-login__main-footer-links-item-link" + ).click() + + # Now we should be at the IDP, wait for the login field + self.wait.until(ec.presence_of_element_located((By.ID, "login"))) + self.driver.find_element(By.ID, "login").send_keys("admin@example.com") + self.driver.find_element(By.ID, "password").send_keys("password") + self.driver.find_element(By.ID, "password").send_keys(Keys.ENTER) + + # Wait until we're logged in + self.wait.until( + ec.presence_of_element_located((By.CSS_SELECTOR, "button[type=submit]")) + ) + self.driver.find_element(By.CSS_SELECTOR, "button[type=submit]").click() + + # At this point we've been redirected back + # and we're asked for the username + sleep(5000) + self.driver.find_element(By.NAME, "username").click() + self.driver.find_element(By.NAME, "username").send_keys("foo") + self.driver.find_element(By.NAME, "username").send_keys(Keys.ENTER) + + # Wait until we've loaded the user info page + self.wait.until(ec.presence_of_element_located((By.LINK_TEXT, "foo"))) + self.driver.find_element(By.LINK_TEXT, "foo").click() + + self.wait_for_url(self.url("passbook_core:user-settings")) + self.assertEqual( + self.driver.find_element(By.XPATH, "//a[contains(@href, '/-/user/')]").text, + "foo", + ) + self.assertEqual( + self.driver.find_element(By.ID, "id_username").get_attribute("value"), "foo" + ) + self.assertEqual( + self.driver.find_element(By.ID, "id_name").get_attribute("value"), "admin", + ) + self.assertEqual( + self.driver.find_element(By.ID, "id_email").get_attribute("value"), + "admin@example.com", + ) diff --git a/passbook/policies/mixins.py b/passbook/policies/mixins.py index 2e298b741..14e6f6e6c 100644 --- a/passbook/policies/mixins.py +++ b/passbook/policies/mixins.py @@ -27,6 +27,7 @@ class PolicyAccessMixin(BaseMixin, AccessMixin): def handle_no_permission_authorized(self) -> HttpResponse: """Function called when user has no permissions but is authorized""" + # TODO: Remove this URL and render the view instead return redirect("passbook_flows:denied") def provider_to_application(self, provider: Provider) -> Application: