From f1a4b212282b5b8e725d70e2c8447df149572507 Mon Sep 17 00:00:00 2001 From: bart-maykin Date: Fri, 2 Aug 2024 01:04:25 +0200 Subject: [PATCH] :arrow_up: [#50] updated dependecies and added oidc tests --- package-lock.json | 129 ++----- requirements/base.txt | 56 ++-- requirements/ci.txt | 70 ++-- requirements/dev.txt | 83 ++--- requirements/test-tools.in | 1 + src/objects/accounts/tests/factories.py | 24 +- .../keycloak_cassets/duplicate_email.yaml | 314 ++++++++++++++++++ .../tests/keycloak_cassets/happy_flow.yaml | 314 ++++++++++++++++++ .../happy_flow_existing_user.yaml | 314 ++++++++++++++++++ src/objects/accounts/tests/test_oidc.py | 104 ++++++ src/objects/api/v2/openapi.yaml | 9 + src/objects/conf/base.py | 10 + .../commands/test_setup_configuration.py | 2 +- src/objects/urls.py | 2 + src/objects/utils/tests/__init__.py | 0 src/objects/utils/tests/keycloak.py | 89 +++++ 16 files changed, 1330 insertions(+), 191 deletions(-) create mode 100644 src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml create mode 100644 src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml create mode 100644 src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml create mode 100644 src/objects/utils/tests/__init__.py create mode 100644 src/objects/utils/tests/keycloak.py diff --git a/package-lock.json b/package-lock.json index 92e002e1..8cb0d4c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "objects", - "version": "2.3.0", + "version": "2.4.0", "license": "UNLICENSED", "dependencies": { "microscope-sass": "latest", @@ -2882,11 +2882,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4014,9 +4014,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", - "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -4028,7 +4028,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" + "ws": "~8.17.1" }, "engines": { "node": ">=10.2.0" @@ -4264,17 +4264,17 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -4305,34 +4305,10 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { "node": ">= 0.6" @@ -4377,21 +4353,6 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4537,9 +4498,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4640,9 +4601,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -8592,12 +8553,13 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "dependencies": { - "ws": "~8.11.0" + "debug": "~4.3.4", + "ws": "~8.17.1" } }, "node_modules/socket.io-parser": { @@ -9521,9 +9483,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { "colorette": "^2.0.10", @@ -9602,27 +9564,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-merge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", @@ -9809,16 +9750,16 @@ "dev": true }, "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { diff --git a/requirements/base.txt b/requirements/base.txt index 04225b7d..75ce49d7 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --no-emit-index-url requirements/base.in @@ -9,6 +9,7 @@ amqp==5.2.0 asgiref==3.7.2 # via # django + # django-axes # django-cors-headers asn1crypto==1.5.1 # via webauthn @@ -16,7 +17,7 @@ attrs==20.3.0 # via # glom # jsonschema -billiard==3.6.4.0 +billiard==4.2.0 # via celery bleach==6.1.0 # via open-api-framework @@ -24,14 +25,14 @@ boltons==21.0.0 # via # face # glom -cbor2==5.6.1 +cbor2==5.6.2 # via webauthn -celery==5.2.7 +celery==5.4.0 # via # flower # notifications-api-common # open-api-framework -certifi==2020.12.5 +certifi==2023.7.22 # via # django-simple-certmanager # elastic-apm @@ -66,7 +67,7 @@ cryptography==41.0.7 # mozilla-django-oidc # pyopenssl # webauthn -django==4.2.11 +django==4.2.14 # via # commonground-api-common # django-admin-index @@ -104,17 +105,17 @@ django-admin-index==3.1.0 # via open-api-framework django-appconf==1.0.6 # via django-log-outgoing-requests -django-axes==6.3.0 +django-axes==6.5.1 # via open-api-framework -django-cors-headers==4.3.1 +django-cors-headers==4.4.0 # via open-api-framework -django-filter==23.5 +django-filter==24.2 # via # commonground-api-common # open-api-framework django-formtools==2.3 # via django-two-factor-auth -django-jsonform==2.21.4 +django-jsonform==2.22.0 # via # mozilla-django-oidc-db # open-api-framework @@ -151,7 +152,7 @@ django-solo==2.2.0 # zgw-consumers django-two-factor-auth[phonenumberslite,webauthn]==1.16.0 # via maykin-2fa -djangorestframework==3.14.0 +djangorestframework==3.15.2 # via # commonground-api-common # djangorestframework-gis @@ -171,13 +172,13 @@ djangorestframework-inclusions==1.2.0 # via open-api-framework drf-nested-routers==0.93.3 # via commonground-api-common -drf-spectacular==0.27.0 +drf-spectacular==0.27.2 # via open-api-framework drf-yasg==1.21.7 # via commonground-api-common ecs-logging==2.1.0 # via elastic-apm -elastic-apm==6.20.0 +elastic-apm==6.23.0 # via open-api-framework face==20.1.1 # via glom @@ -198,7 +199,7 @@ glom==23.5.0 # mozilla-django-oidc-db humanize==4.9.0 # via flower -idna==2.10 +idna==3.7 # via requests inflection==0.5.1 # via @@ -210,7 +211,7 @@ isodate==0.6.0 # via commonground-api-common itypes==1.2.0 # via coreapi -jinja2==3.1.3 +jinja2==3.1.4 # via coreschema josepy==1.9.0 # via mozilla-django-oidc @@ -222,17 +223,17 @@ kombu==5.3.5 # via celery markupsafe==2.1.3 # via jinja2 -maykin-2fa==1.0.0 +maykin-2fa==1.0.1 # via open-api-framework mozilla-django-oidc==4.0.0 # via mozilla-django-oidc-db -mozilla-django-oidc-db==0.14.1 +mozilla-django-oidc-db==0.19.0 # via open-api-framework notifications-api-common==0.2.2 # via # -r requirements/base.in # commonground-api-common -open-api-framework==0.5.0 +open-api-framework==0.6.1 # via -r requirements/base.in orderedmultidict==1.0.1 # via furl @@ -262,8 +263,9 @@ pyopenssl==23.3.0 # zgw-consumers pyrsistent==0.17.3 # via jsonschema -python-dateutil==2.8.1 +python-dateutil==2.9.0.post0 # via + # celery # django-relativedelta # faker python-decouple==3.8 @@ -272,8 +274,6 @@ python-dotenv==1.0.0 # via open-api-framework pytz==2024.1 # via - # celery - # djangorestframework # drf-yasg # flower pyyaml==6.0.1 @@ -286,7 +286,7 @@ qrcode==6.1 # via django-two-factor-auth redis==3.5.3 # via django-redis -requests==2.31.0 +requests==2.32.3 # via # commonground-api-common # coreapi @@ -298,7 +298,7 @@ requests==2.31.0 # zgw-consumers requests-mock==1.8.0 # via zgw-consumers -sentry-sdk==1.39.2 +sentry-sdk==2.12.0 # via open-api-framework six==1.16.0 # via @@ -309,20 +309,22 @@ six==1.16.0 # python-dateutil # qrcode # requests-mock -sqlparse==0.4.2 +sqlparse==0.5.0 # via django text-unidecode==1.3 # via faker -tornado==6.4 +tornado==6.4.1 # via flower typing-extensions==4.9.0 - # via asgiref + # via mozilla-django-oidc-db +tzdata==2024.1 + # via celery uritemplate==3.0.1 # via # coreapi # drf-spectacular # drf-yasg -urllib3==2.2.1 +urllib3==2.2.2 # via # elastic-apm # requests diff --git a/requirements/ci.txt b/requirements/ci.txt index 7be57728..c7a5300a 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --no-emit-index-url --output-file=requirements/ci.txt requirements/base.txt requirements/test-tools.in @@ -12,6 +12,7 @@ asgiref==3.7.2 # via # -r requirements/base.txt # django + # django-axes # django-cors-headers asn1crypto==1.5.1 # via @@ -24,7 +25,7 @@ attrs==20.3.0 # jsonschema beautifulsoup4==4.9.3 # via webtest -billiard==3.6.4.0 +billiard==4.2.0 # via # -r requirements/base.txt # celery @@ -37,17 +38,17 @@ boltons==21.0.0 # -r requirements/base.txt # face # glom -cbor2==5.6.1 +cbor2==5.6.2 # via # -r requirements/base.txt # webauthn -celery==5.2.7 +celery==5.4.0 # via # -r requirements/base.txt # flower # notifications-api-common # open-api-framework -certifi==2020.12.5 +certifi==2023.7.22 # via # -r requirements/base.txt # django-simple-certmanager @@ -105,7 +106,7 @@ cryptography==41.0.7 # webauthn cssselect==1.1.0 # via pyquery -django==4.2.11 +django==4.2.14 # via # -r requirements/base.txt # commonground-api-common @@ -148,15 +149,15 @@ django-appconf==1.0.6 # via # -r requirements/base.txt # django-log-outgoing-requests -django-axes==6.3.0 +django-axes==6.5.1 # via # -r requirements/base.txt # open-api-framework -django-cors-headers==4.3.1 +django-cors-headers==4.4.0 # via # -r requirements/base.txt # open-api-framework -django-filter==23.5 +django-filter==24.2 # via # -r requirements/base.txt # commonground-api-common @@ -165,7 +166,7 @@ django-formtools==2.3 # via # -r requirements/base.txt # django-two-factor-auth -django-jsonform==2.21.4 +django-jsonform==2.22.0 # via # -r requirements/base.txt # mozilla-django-oidc-db @@ -229,11 +230,10 @@ django-solo==2.2.0 django-two-factor-auth[phonenumberslite,webauthn]==1.16.0 # via # -r requirements/base.txt - # django-two-factor-auth # maykin-2fa django-webtest==1.9.7 # via -r requirements/test-tools.in -djangorestframework==3.14.0 +djangorestframework==3.15.2 # via # -r requirements/base.txt # commonground-api-common @@ -261,7 +261,7 @@ drf-nested-routers==0.93.3 # via # -r requirements/base.txt # commonground-api-common -drf-spectacular==0.27.0 +drf-spectacular==0.27.2 # via # -r requirements/base.txt # open-api-framework @@ -273,7 +273,7 @@ ecs-logging==2.1.0 # via # -r requirements/base.txt # elastic-apm -elastic-apm==6.20.0 +elastic-apm==6.23.0 # via # -r requirements/base.txt # open-api-framework @@ -310,10 +310,11 @@ humanize==4.9.0 # via # -r requirements/base.txt # flower -idna==2.10 +idna==3.7 # via # -r requirements/base.txt # requests + # yarl inflection==0.5.1 # via # -r requirements/base.txt @@ -331,7 +332,7 @@ itypes==1.2.0 # via # -r requirements/base.txt # coreapi -jinja2==3.1.3 +jinja2==3.1.4 # via # -r requirements/base.txt # coreschema @@ -353,7 +354,7 @@ markupsafe==2.1.3 # via # -r requirements/base.txt # jinja2 -maykin-2fa==1.0.0 +maykin-2fa==1.0.1 # via # -r requirements/base.txt # open-api-framework @@ -361,15 +362,17 @@ mozilla-django-oidc==4.0.0 # via # -r requirements/base.txt # mozilla-django-oidc-db -mozilla-django-oidc-db==0.14.1 +mozilla-django-oidc-db==0.19.0 # via # -r requirements/base.txt # open-api-framework +multidict==6.0.5 + # via yarl notifications-api-common==0.2.2 # via # -r requirements/base.txt # commonground-api-common -open-api-framework==0.5.0 +open-api-framework==0.6.1 # via -r requirements/base.txt orderedmultidict==1.0.1 # via @@ -421,9 +424,10 @@ pyrsistent==0.17.3 # via # -r requirements/base.txt # jsonschema -python-dateutil==2.8.1 +python-dateutil==2.9.0.post0 # via # -r requirements/base.txt + # celery # django-relativedelta # faker # freezegun @@ -438,8 +442,6 @@ python-dotenv==1.0.0 pytz==2024.1 # via # -r requirements/base.txt - # celery - # djangorestframework # drf-yasg # flower pyyaml==6.0.1 @@ -449,6 +451,7 @@ pyyaml==6.0.1 # drf-yasg # gemma-zds-client # oyaml + # vcrpy qrcode==6.1 # via # -r requirements/base.txt @@ -457,7 +460,7 @@ redis==3.5.3 # via # -r requirements/base.txt # django-redis -requests==2.31.0 +requests==2.32.3 # via # -r requirements/base.txt # commonground-api-common @@ -473,7 +476,7 @@ requests-mock==1.8.0 # -r requirements/base.txt # -r requirements/test-tools.in # zgw-consumers -sentry-sdk==1.39.2 +sentry-sdk==2.12.0 # via # -r requirements/base.txt # open-api-framework @@ -490,7 +493,7 @@ six==1.16.0 # webtest soupsieve==2.2.1 # via beautifulsoup4 -sqlparse==0.4.2 +sqlparse==0.5.0 # via # -r requirements/base.txt # django @@ -500,21 +503,25 @@ text-unidecode==1.3 # via # -r requirements/base.txt # faker -tornado==6.4 +tornado==6.4.1 # via # -r requirements/base.txt # flower typing-extensions==4.9.0 # via # -r requirements/base.txt - # asgiref + # mozilla-django-oidc-db +tzdata==2024.1 + # via + # -r requirements/base.txt + # celery uritemplate==3.0.1 # via # -r requirements/base.txt # coreapi # drf-spectacular # drf-yasg -urllib3==2.2.1 +urllib3==2.2.2 # via # -r requirements/base.txt # elastic-apm @@ -524,13 +531,15 @@ uwsgi==2.0.23 # via # -r requirements/base.txt # open-api-framework +vcrpy==6.0.1 + # via -r requirements/test-tools.in vine==5.1.0 # via # -r requirements/base.txt # amqp # celery # kombu -waitress==2.1.1 +waitress==2.1.2 # via webtest wcwidth==0.2.13 # via @@ -552,6 +561,9 @@ wrapt==1.14.1 # via # -r requirements/base.txt # elastic-apm + # vcrpy +yarl==1.9.4 + # via vcrpy zgw-consumers==0.27.0 # via # -r requirements/base.txt diff --git a/requirements/dev.txt b/requirements/dev.txt index fc78f832..e6a3cb71 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --no-emit-index-url --output-file=requirements/dev.txt requirements/ci.txt requirements/dev.in @@ -14,6 +14,7 @@ asgiref==3.7.2 # via # -r requirements/ci.txt # django + # django-axes # django-cors-headers asn1crypto==1.5.1 # via @@ -30,11 +31,11 @@ beautifulsoup4==4.9.3 # via # -r requirements/ci.txt # webtest -billiard==3.6.4.0 +billiard==4.2.0 # via # -r requirements/ci.txt # celery -black==23.12.1 +black==24.3.0 # via -r requirements/dev.in bleach==6.1.0 # via @@ -51,17 +52,17 @@ bump2version==1.0.1 # via bumpversion bumpversion==0.6.0 # via -r requirements/dev.in -cbor2==5.6.1 +cbor2==5.6.2 # via # -r requirements/ci.txt # webauthn -celery==5.2.7 +celery==5.4.0 # via # -r requirements/ci.txt # flower # notifications-api-common # open-api-framework -certifi==2020.12.5 +certifi==2023.7.22 # via # -r requirements/ci.txt # django-simple-certmanager @@ -125,7 +126,7 @@ cssselect==1.1.0 # via # -r requirements/ci.txt # pyquery -django==4.2.11 +django==4.2.14 # via # -r requirements/ci.txt # commonground-api-common @@ -170,11 +171,11 @@ django-appconf==1.0.6 # via # -r requirements/ci.txt # django-log-outgoing-requests -django-axes==6.3.0 +django-axes==6.5.1 # via # -r requirements/ci.txt # open-api-framework -django-cors-headers==4.3.1 +django-cors-headers==4.4.0 # via # -r requirements/ci.txt # open-api-framework @@ -182,7 +183,7 @@ django-debug-toolbar==4.2.0 # via -r requirements/dev.in django-extensions==3.2.3 # via -r requirements/dev.in -django-filter==23.5 +django-filter==24.2 # via # -r requirements/ci.txt # commonground-api-common @@ -191,7 +192,7 @@ django-formtools==2.3 # via # -r requirements/ci.txt # django-two-factor-auth -django-jsonform==2.21.4 +django-jsonform==2.22.0 # via # -r requirements/ci.txt # mozilla-django-oidc-db @@ -255,11 +256,10 @@ django-solo==2.2.0 django-two-factor-auth[phonenumberslite,webauthn]==1.16.0 # via # -r requirements/ci.txt - # django-two-factor-auth # maykin-2fa django-webtest==1.9.7 # via -r requirements/ci.txt -djangorestframework==3.14.0 +djangorestframework==3.15.2 # via # -r requirements/ci.txt # commonground-api-common @@ -293,7 +293,7 @@ drf-nested-routers==0.93.3 # via # -r requirements/ci.txt # commonground-api-common -drf-spectacular==0.27.0 +drf-spectacular==0.27.2 # via # -r requirements/ci.txt # open-api-framework @@ -305,7 +305,7 @@ ecs-logging==2.1.0 # via # -r requirements/ci.txt # elastic-apm -elastic-apm==6.20.0 +elastic-apm==6.23.0 # via # -r requirements/ci.txt # open-api-framework @@ -344,10 +344,11 @@ humanize==4.9.0 # via # -r requirements/ci.txt # flower -idna==2.10 +idna==3.7 # via # -r requirements/ci.txt # requests + # yarl imagesize==1.4.1 # via sphinx inflection==0.5.1 @@ -369,7 +370,7 @@ itypes==1.2.0 # via # -r requirements/ci.txt # coreapi -jinja2==3.1.3 +jinja2==3.1.4 # via # -r requirements/ci.txt # coreschema @@ -394,7 +395,7 @@ markupsafe==2.1.3 # via # -r requirements/ci.txt # jinja2 -maykin-2fa==1.0.0 +maykin-2fa==1.0.1 # via # -r requirements/ci.txt # open-api-framework @@ -404,17 +405,21 @@ mozilla-django-oidc==4.0.0 # via # -r requirements/ci.txt # mozilla-django-oidc-db -mozilla-django-oidc-db==0.14.1 +mozilla-django-oidc-db==0.19.0 # via # -r requirements/ci.txt # open-api-framework +multidict==6.0.5 + # via + # -r requirements/ci.txt + # yarl mypy-extensions==0.4.3 # via black notifications-api-common==0.2.2 # via # -r requirements/ci.txt # commonground-api-common -open-api-framework==0.5.0 +open-api-framework==0.6.1 # via -r requirements/ci.txt orderedmultidict==1.0.1 # via @@ -485,9 +490,10 @@ pyrsistent==0.17.3 # via # -r requirements/ci.txt # jsonschema -python-dateutil==2.8.1 +python-dateutil==2.9.0.post0 # via # -r requirements/ci.txt + # celery # django-relativedelta # faker # freezegun @@ -503,8 +509,6 @@ pytz==2024.1 # via # -r requirements/ci.txt # babel - # celery - # djangorestframework # drf-yasg # flower pyyaml==6.0.1 @@ -514,6 +518,7 @@ pyyaml==6.0.1 # drf-yasg # gemma-zds-client # oyaml + # vcrpy qrcode==6.1 # via # -r requirements/ci.txt @@ -524,7 +529,7 @@ redis==3.5.3 # via # -r requirements/ci.txt # django-redis -requests==2.31.0 +requests==2.32.3 # via # -r requirements/ci.txt # commonground-api-common @@ -540,7 +545,7 @@ requests-mock==1.8.0 # via # -r requirements/ci.txt # zgw-consumers -sentry-sdk==1.39.2 +sentry-sdk==2.12.0 # via # -r requirements/ci.txt # open-api-framework @@ -586,7 +591,7 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -sqlparse==0.4.2 +sqlparse==0.5.0 # via # -r requirements/ci.txt # django @@ -597,28 +602,25 @@ text-unidecode==1.3 # via # -r requirements/ci.txt # faker -tomli==2.0.1 - # via - # black - # build - # pip-tools - # pyproject-hooks -tornado==6.4 +tornado==6.4.1 # via # -r requirements/ci.txt # flower typing-extensions==4.9.0 # via # -r requirements/ci.txt - # asgiref - # black + # mozilla-django-oidc-db +tzdata==2024.1 + # via + # -r requirements/ci.txt + # celery uritemplate==3.0.1 # via # -r requirements/ci.txt # coreapi # drf-spectacular # drf-yasg -urllib3==2.2.1 +urllib3==2.2.2 # via # -r requirements/ci.txt # elastic-apm @@ -628,13 +630,15 @@ uwsgi==2.0.23 # via # -r requirements/ci.txt # open-api-framework +vcrpy==6.0.1 + # via -r requirements/ci.txt vine==5.1.0 # via # -r requirements/ci.txt # amqp # celery # kombu -waitress==2.1.1 +waitress==2.1.2 # via # -r requirements/ci.txt # webtest @@ -664,6 +668,11 @@ wrapt==1.14.1 # via # -r requirements/ci.txt # elastic-apm + # vcrpy +yarl==1.9.4 + # via + # -r requirements/ci.txt + # vcrpy zgw-consumers==0.27.0 # via # -r requirements/ci.txt diff --git a/requirements/test-tools.in b/requirements/test-tools.in index f6f5c01d..e9d49af0 100644 --- a/requirements/test-tools.in +++ b/requirements/test-tools.in @@ -6,3 +6,4 @@ freezegun pyquery # integrates with webtest requests-mock tblib +vcrpy diff --git a/src/objects/accounts/tests/factories.py b/src/objects/accounts/tests/factories.py index 5b8130b1..843f3953 100644 --- a/src/objects/accounts/tests/factories.py +++ b/src/objects/accounts/tests/factories.py @@ -1,8 +1,26 @@ -import factory.fuzzy +from django.contrib.auth import get_user_model +import factory +from factory.django import DjangoModelFactory -class UserFactory(factory.django.DjangoModelFactory): +User = get_user_model() + + +class UserFactory(DjangoModelFactory): username = factory.Sequence(lambda n: f"user-{n}") + first_name = factory.Faker("first_name") + last_name = factory.Faker("last_name") + password = factory.PostGenerationMethodCall("set_password", "password") class Meta: - model = "accounts.User" + model = User + + class Params: + superuser = factory.Trait( + is_staff=True, + is_superuser=True, + ) + + +class StaffUserFactory(UserFactory): + is_staff = True diff --git a/src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml b/src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml new file mode 100644 index 00000000..a0d778ab --- /dev/null +++ b/src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml @@ -0,0 +1,314 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=testid&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F&state=not-a-random-string&nonce=not-a-random-string + response: + body: + string: "\n\n\n\n \n + \ \n \n\n \n Sign + in to test\n \n \n \n \n \n \n \n\n\n\n
\n + \
\n
test
\n
\n
\n + \
\n

+ \ Sign in to your account\n\n

\n
\n
\n + \
\n\n\n
\n + \
\n
\n
\n \n\n \n\n\n
\n\n
\n \n\n
\n + \ \n \n + \
\n\n\n
\n\n
\n
\n + \
\n
\n + \
\n\n
\n\n
\n \n \n
\n + \
\n
\n
\n \n\n\n\n\n\n + \
\n
\n\n
\n
\n\n\n" + headers: + Cache-Control: + - no-store, must-revalidate, max-age=0 + Content-Language: + - en + Content-Security-Policy: + - frame-src 'self'; frame-ancestors 'self'; object-src 'none'; + Content-Type: + - text/html;charset=utf-8 + Referrer-Policy: + - no-referrer + Set-Cookie: + - AUTH_SESSION_ID=f4033f92-6082-4b67-91de-204b6293d837; Version=1; Path=/realms/test/; + SameSite=None; Secure; HttpOnly + - AUTH_SESSION_ID_LEGACY=f4033f92-6082-4b67-91de-204b6293d837; Version=1; Path=/realms/test/; + HttpOnly + - KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI; + Version=1; Path=/realms/test/; HttpOnly + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Robots-Tag: + - none + X-XSS-Protection: + - 1; mode=block + content-length: + - '4466' + status: + code: 200 + message: OK +- request: + body: username=admin&password=admin&credentialId=&login=Sign+In + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + Content-Length: + - '57' + Content-Type: + - application/x-www-form-urlencoded + Cookie: + - AUTH_SESSION_ID_LEGACY=f4033f92-6082-4b67-91de-204b6293d837; KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8080/realms/test/login-actions/authenticate?session_code=ekaLl2knQ5W0JOqU-pWd9EJUL04yHboA65r0sLewO0o&execution=670fb55e-641e-4beb-bd17-3c0cb001b805&client_id=testid&tab_id=T1IA4iU9hSw + response: + body: + string: '' + headers: + Cache-Control: + - no-store, must-revalidate, max-age=0 + Content-Security-Policy: + - frame-src 'self'; frame-ancestors 'self'; object-src 'none'; + Location: + - http://testserver/oidc/callback/?state=not-a-random-string&session_state=f4033f92-6082-4b67-91de-204b6293d837&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Ftest&code=a60785e5-c76b-4abb-bae7-bcb8b677f352.f4033f92-6082-4b67-91de-204b6293d837.adf4ad83-4550-4619-9231-73bd8d700f45 + Referrer-Policy: + - no-referrer + Set-Cookie: + - KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 + 00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly + - KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; + Path=/realms/test/; HttpOnly + - KC_AUTH_STATE=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; + Path=/realms/test/ + - KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjAxNTU4MzIsImlhdCI6MTcyMDExOTgzMiwianRpIjoiOTVhMjNhODItZTJkNy00MjhiLTk2YzMtZTQ3MTY4MWZlZjE2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJzaWQiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJzdGF0ZV9jaGVja2VyIjoiejJ6RTJOQUQtVl9MQWFGempodUduU25GUWtfM3J6djROb0Z6bnJkSmNTdyJ9.xUSgByKk3ctl91InyibAfW-GyBBzpuE98GqWETzVFnc; + Version=1; Path=/realms/test/; SameSite=None; Secure; HttpOnly + - KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjAxNTU4MzIsImlhdCI6MTcyMDExOTgzMiwianRpIjoiOTVhMjNhODItZTJkNy00MjhiLTk2YzMtZTQ3MTY4MWZlZjE2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJzaWQiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJzdGF0ZV9jaGVja2VyIjoiejJ6RTJOQUQtVl9MQWFGempodUduU25GUWtfM3J6djROb0Z6bnJkSmNTdyJ9.xUSgByKk3ctl91InyibAfW-GyBBzpuE98GqWETzVFnc; + Version=1; Path=/realms/test/; HttpOnly + - KEYCLOAK_SESSION=test/6db2db87-de31-4e30-9f25-cefe5da8b154/f4033f92-6082-4b67-91de-204b6293d837; + Version=1; Expires=Fri, 05-Jul-2024 05:03:52 GMT; Max-Age=36000; Path=/realms/test/; + SameSite=None; Secure + - KEYCLOAK_SESSION_LEGACY=test/6db2db87-de31-4e30-9f25-cefe5da8b154/f4033f92-6082-4b67-91de-204b6293d837; + Version=1; Expires=Fri, 05-Jul-2024 05:03:52 GMT; Max-Age=36000; Path=/realms/test/ + - KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 + 00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Robots-Tag: + - none + X-XSS-Protection: + - 1; mode=block + content-length: + - '0' + status: + code: 302 + message: Found +- request: + body: client_id=testid&client_secret=7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I&grant_type=authorization_code&code=a60785e5-c76b-4abb-bae7-bcb8b677f352.f4033f92-6082-4b67-91de-204b6293d837.adf4ad83-4550-4619-9231-73bd8d700f45&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + Content-Length: + - '267' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8080/realms/test/protocol/openid-connect/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjAxMjAxMzIsImlhdCI6MTcyMDExOTgzMiwiYXV0aF90aW1lIjoxNzIwMTE5ODMyLCJqdGkiOiJmZWNlMjkyNC0yNWE0LTQ3ZDQtYTU5OS0xZDZkZjMyNTQwMTAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6ImY0MDMzZjkyLTYwODItNGI2Ny05MWRlLTIwNGI2MjkzZDgzNyIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6ImY0MDMzZjkyLTYwODItNGI2Ny05MWRlLTIwNGI2MjkzZDgzNyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.tZi3mh6PY61AgfGs8SKfN6KFZFUlnbWke1bJTsESZWfgCqKJIr3rNFMGVZIke70VaSlfop_m-4w6om-ZWmO7Z-6aOGbG93-QDjfsXlLW331u8-hZBD2CYKjZuMXo6Pno6SmI2It_L6I0ZGgsVPsXNM6Vx_dYerL3LXOpfw4R3QMElKOvb9llTpsgByYkWnDJrP8nCPHGQvWjkYepNkC6C1Hg51NT6l3MROQt5KDT74NWwFIfsYc2RPIABRVWY-vuWF_w01-zPkf34kfV5-02Qv8VYcQbFEx0oDbDzMHeDOzI6Je1RCwBsgEjy8OAtXrVwwJSUSx3qSyMYZlwkoGgbw","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjAxMjE2MzIsImlhdCI6MTcyMDExOTgzMiwianRpIjoiYjUwNWQzNjYtNjAxNC00MmNlLTk0M2EtZDEyMmEzMzY5MjBkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIGt2ayBncm91cHMgYnNuIiwic2lkIjoiZjQwMzNmOTItNjA4Mi00YjY3LTkxZGUtMjA0YjYyOTNkODM3In0.Wp4GdI_ynIGdc-ZzPSml8PkkXWywFMqBvcyv_J_JslI","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjAxMjAxMzIsImlhdCI6MTcyMDExOTgzMiwiYXV0aF90aW1lIjoxNzIwMTE5ODMyLCJqdGkiOiI2ZjYyMmFiZi00ZTRhLTRjNTQtYjBjZi1hZTFiYTk5NTY0MWIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJ0ZXN0aWQiLCJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJ0eXAiOiJJRCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJhdF9oYXNoIjoiQWplTjMzdEtFUUpjblY2M1hOMVVHUSIsImFjciI6IjEiLCJzaWQiOiJmNDAzM2Y5Mi02MDgyLTRiNjctOTFkZS0yMDRiNjI5M2Q4MzciLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.UWne7fWO36zAESCpdGsGuDZj0FwFggt75MwCgOebJ23mXLKqhIhWsuPD-ST4QsYouwkf1ref0fXqZDCMcDFCikBEK5zc-Gqw4OTeAIkwwUx_J5CFCWA64pJKYgt2rqOgems9wsLLY3DssW8BzGpqB74biTtqtlt2O6qHHaenH1F5e_Y3bSHuiUhxR7EQnG83IOpd4cPwVteU6lxkAIXUVq85Xso_Ntu_DBcnMRyCdx8uYbT3K2C8iLt9SojtQ13szTefWtj6ygSNTmoR0rpj2mQuX6ouKAxh1q3kMHTgvKLcEkUda7TzHNuomPQ0U5mQFJBzpGJ8KWtS2s7MIoEJhw","not-before-policy":0,"session_state":"f4033f92-6082-4b67-91de-204b6293d837","scope":"openid + email profile kvk groups bsn"}' + headers: + Cache-Control: + - no-store + Content-Type: + - application/json + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '3698' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/certs + response: + body: + string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;charset=UTF-8 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '2909' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Authorization: + - Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjAxMjAxMzIsImlhdCI6MTcyMDExOTgzMiwiYXV0aF90aW1lIjoxNzIwMTE5ODMyLCJqdGkiOiJmZWNlMjkyNC0yNWE0LTQ3ZDQtYTU5OS0xZDZkZjMyNTQwMTAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6ImY0MDMzZjkyLTYwODItNGI2Ny05MWRlLTIwNGI2MjkzZDgzNyIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6ImY0MDMzZjkyLTYwODItNGI2Ny05MWRlLTIwNGI2MjkzZDgzNyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.tZi3mh6PY61AgfGs8SKfN6KFZFUlnbWke1bJTsESZWfgCqKJIr3rNFMGVZIke70VaSlfop_m-4w6om-ZWmO7Z-6aOGbG93-QDjfsXlLW331u8-hZBD2CYKjZuMXo6Pno6SmI2It_L6I0ZGgsVPsXNM6Vx_dYerL3LXOpfw4R3QMElKOvb9llTpsgByYkWnDJrP8nCPHGQvWjkYepNkC6C1Hg51NT6l3MROQt5KDT74NWwFIfsYc2RPIABRVWY-vuWF_w01-zPkf34kfV5-02Qv8VYcQbFEx0oDbDzMHeDOzI6Je1RCwBsgEjy8OAtXrVwwJSUSx3qSyMYZlwkoGgbw + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/userinfo + response: + body: + string: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJhdWQiOiJ0ZXN0aWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.vx4dCJ-Y-PEzjy8p7CNPB3yy0TyV_QugOHRbiV6UY3qHtZUnZqSsJD991QUostcYECuyTHefqfRtdCbvSJcPWI4ucosY65vshUMBtQeahsFOgNwWp2BvCkALJmEya4H_gh63vVlVZ2ZOSpWpah6eV2PNhiiYWD-Y9qEuLMzwngNvp5hna30BiRKAEsStB7izjE5pGECqkQm7pxCeZWHU81Lbh5fSo_2XvcGZ1Z-tf6DN95Oz4ers9YrG6dKSuh-HciY1zhv7mcee_tlJaeKjITue6r06163oKdjsYKRpiR4bLQ9256KafoxmU6O0IIlpkQhmtXrmaFSg0XyBYU8qcQ + headers: + Cache-Control: + - no-cache + Content-Type: + - application/jwt + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-XSS-Protection: + - 1; mode=block + content-length: + - '813' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/certs + response: + body: + string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;charset=UTF-8 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '2909' + status: + code: 200 + message: OK +version: 1 diff --git a/src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml b/src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml new file mode 100644 index 00000000..388adf3d --- /dev/null +++ b/src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml @@ -0,0 +1,314 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=testid&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F&state=not-a-random-string&nonce=not-a-random-string + response: + body: + string: "\n\n\n\n \n + \ \n \n\n \n Sign + in to test\n \n \n \n \n \n \n \n\n\n\n
\n + \
\n
test
\n
\n
\n + \
\n

+ \ Sign in to your account\n\n

\n
\n
\n + \
\n\n\n
\n + \
\n
\n
\n \n\n \n\n\n
\n\n
\n \n\n
\n + \ \n \n + \
\n\n\n
\n\n
\n
\n + \
\n
\n + \
\n\n
\n\n
\n \n \n
\n + \
\n
\n
\n \n\n\n\n\n\n + \
\n
\n\n
\n
\n\n\n" + headers: + Cache-Control: + - no-store, must-revalidate, max-age=0 + Content-Language: + - en + Content-Security-Policy: + - frame-src 'self'; frame-ancestors 'self'; object-src 'none'; + Content-Type: + - text/html;charset=utf-8 + Referrer-Policy: + - no-referrer + Set-Cookie: + - AUTH_SESSION_ID=fd1dfa4b-5306-4095-a37d-64c6122de3b2; Version=1; Path=/realms/test/; + SameSite=None; Secure; HttpOnly + - AUTH_SESSION_ID_LEGACY=fd1dfa4b-5306-4095-a37d-64c6122de3b2; Version=1; Path=/realms/test/; + HttpOnly + - KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI; + Version=1; Path=/realms/test/; HttpOnly + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Robots-Tag: + - none + X-XSS-Protection: + - 1; mode=block + content-length: + - '4474' + status: + code: 200 + message: OK +- request: + body: username=admin&password=admin&credentialId=&login=Sign+In + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '57' + Content-Type: + - application/x-www-form-urlencoded + Cookie: + - AUTH_SESSION_ID_LEGACY=fd1dfa4b-5306-4095-a37d-64c6122de3b2; KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI + User-Agent: + - python-requests/2.32.3 + method: POST + uri: http://localhost:8080/realms/test/login-actions/authenticate?session_code=_BlhjuNy-r1uZKZi6uW7-MuqhG0ssYsdl32-1WXsHLE&execution=d5d6e7a6-23bf-482a-9dba-67b020da2142&client_id=testid&tab_id=Ve6V_UZ-O7k + response: + body: + string: '' + headers: + Cache-Control: + - no-store, must-revalidate, max-age=0 + Content-Security-Policy: + - frame-src 'self'; frame-ancestors 'self'; object-src 'none'; + Location: + - http://testserver/oidc/callback/?state=not-a-random-string&session_state=fd1dfa4b-5306-4095-a37d-64c6122de3b2&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Ftest&code=cae98c69-0cc1-40b9-b9ae-f17ea06e4b10.fd1dfa4b-5306-4095-a37d-64c6122de3b2.adf4ad83-4550-4619-9231-73bd8d700f45 + Referrer-Policy: + - no-referrer + Set-Cookie: + - KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 + 00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly + - KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; + Path=/realms/test/; HttpOnly + - KC_AUTH_STATE=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; + Path=/realms/test/ + - KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjI1ODM1ODMsImlhdCI6MTcyMjU0NzU4MywianRpIjoiODRhZDFhZmQtNDU2NS00NzJmLWE2ZmQtNDY5ZWRkNTZiYWMxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiMTM1NmMyYzItMDFlMC00MjhlLThmOTMtOWEwZGQ4Yzk1M2ZmIiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJzaWQiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJzdGF0ZV9jaGVja2VyIjoiZ29fTVNBX2VzR014OHF4S0Y0UkwxbUREUHNaVGUwczJMeXBsSEdHdmNNMCJ9.IcKOQwbSaTu1K9vWpy7LnzWalO4-snhnv4G_cN0cjdE; + Version=1; Path=/realms/test/; SameSite=None; Secure; HttpOnly + - KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjI1ODM1ODMsImlhdCI6MTcyMjU0NzU4MywianRpIjoiODRhZDFhZmQtNDU2NS00NzJmLWE2ZmQtNDY5ZWRkNTZiYWMxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiMTM1NmMyYzItMDFlMC00MjhlLThmOTMtOWEwZGQ4Yzk1M2ZmIiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJzaWQiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJzdGF0ZV9jaGVja2VyIjoiZ29fTVNBX2VzR014OHF4S0Y0UkwxbUREUHNaVGUwczJMeXBsSEdHdmNNMCJ9.IcKOQwbSaTu1K9vWpy7LnzWalO4-snhnv4G_cN0cjdE; + Version=1; Path=/realms/test/; HttpOnly + - KEYCLOAK_SESSION=test/1356c2c2-01e0-428e-8f93-9a0dd8c953ff/fd1dfa4b-5306-4095-a37d-64c6122de3b2; + Version=1; Expires=Fri, 02-Aug-2024 07:26:23 GMT; Max-Age=36000; Path=/realms/test/; + SameSite=None; Secure + - KEYCLOAK_SESSION_LEGACY=test/1356c2c2-01e0-428e-8f93-9a0dd8c953ff/fd1dfa4b-5306-4095-a37d-64c6122de3b2; + Version=1; Expires=Fri, 02-Aug-2024 07:26:23 GMT; Max-Age=36000; Path=/realms/test/ + - KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 + 00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Robots-Tag: + - none + X-XSS-Protection: + - 1; mode=block + content-length: + - '0' + status: + code: 302 + message: Found +- request: + body: client_id=testid&client_secret=7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I&grant_type=authorization_code&code=cae98c69-0cc1-40b9-b9ae-f17ea06e4b10.fd1dfa4b-5306-4095-a37d-64c6122de3b2.adf4ad83-4550-4619-9231-73bd8d700f45&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '267' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.32.3 + method: POST + uri: http://localhost:8080/realms/test/protocol/openid-connect/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjI1NDc4ODMsImlhdCI6MTcyMjU0NzU4MywiYXV0aF90aW1lIjoxNzIyNTQ3NTgzLCJqdGkiOiJmYjU0NmI1Mi0wMDcyLTQ3M2UtYWVmYS03MTcwMjMzZjljOTciLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMTM1NmMyYzItMDFlMC00MjhlLThmOTMtOWEwZGQ4Yzk1M2ZmIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6ImZkMWRmYTRiLTUzMDYtNDA5NS1hMzdkLTY0YzYxMjJkZTNiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgYnNuIiwic2lkIjoiZmQxZGZhNGItNTMwNi00MDk1LWEzN2QtNjRjNjEyMmRlM2IyIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJhZG1pbiBhZG1pbiIsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6ImFkbWluIiwiZmFtaWx5X25hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AYWRtaW4uYWRtaW4ifQ.in3vUi9Ml3XQSZ74DMDYUeLIjkcwmxl6r2yL0TSHfATYicjkLjx4YPyicF8NdgiXSHgjoz-zRYMqvNLmcV5gs-pNfLQ0D5hlEvv0UYEM5KsJe6x_FWqUKXkldeHl5L0TUIdzWrkJWLSzxdkK0hjbLVbqPG9JHf7V0OJyQcRF4syXoHj5CAXDn1IThVGN4WojkQwZAiv_CWYOlVVDlCU5cRP68pszf32K4ePkPVkl-YrBxJ9ZYoOofLEWe0PSjActdpjnsRKRQW5Vs0pjLsFnt7yX20NrvzH_lQy25wZArhYS4NL7UgZqugsIyCulzXoedNv-J655_gQSoq52utIkww","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjI1NDkzODMsImlhdCI6MTcyMjU0NzU4MywianRpIjoiMTllNDM1YmItYzBjNy00MGM5LTk4OGItYzIxZmZlMTUzMzU0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiMTM1NmMyYzItMDFlMC00MjhlLThmOTMtOWEwZGQ4Yzk1M2ZmIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIGt2ayBic24iLCJzaWQiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIifQ.xypid3BhX4BhjW-OXTlmtaV2_pa0mY5mLXmmV1rzfo0","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjI1NDc4ODMsImlhdCI6MTcyMjU0NzU4MywiYXV0aF90aW1lIjoxNzIyNTQ3NTgzLCJqdGkiOiJiMDM4MzY2Yi02ZDU0LTQ5ZTQtOTgwMS1iNjZhMWVhYWM2YjUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJ0ZXN0aWQiLCJzdWIiOiIxMzU2YzJjMi0wMWUwLTQyOGUtOGY5My05YTBkZDhjOTUzZmYiLCJ0eXAiOiJJRCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJhdF9oYXNoIjoiMnJDNGdxM3ZvOWF5a1FpX0FXOV9wQSIsImFjciI6IjEiLCJzaWQiOiJmZDFkZmE0Yi01MzA2LTQwOTUtYTM3ZC02NGM2MTIyZGUzYjIiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6ImFkbWluIGFkbWluIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJnaXZlbl9uYW1lIjoiYWRtaW4iLCJmYW1pbHlfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBhZG1pbi5hZG1pbiJ9.WIcn6D7fw3Hp1T6iA7C7nj46ivX0vbvwjl1P9UQT5CcmM8tVOoD8Bs85WtnfpdWwFsCgfcTBXKt_Mpr007ThZzdY67GssbQ50d7uKwb2ilUDxA4OU3fLtq9qBxtzk3xp3WxEaKxJ7i9IlBjPtdHARJlpAfvrS7CTVyUbWIeA-Gd_6rCXUFozOBsIqL9gpqXaBYj0XeleXhgtB_yhphHLrZvCxNK3jPcBlsT-fUx54RdDqBFm54mmoXss3A5xNp1YpnkpJ33QjN0DKf540Zc3IwA2Go8Cd_26XFUwpPJD5GBZIAC91a90X-EYbknqOBY47Ll8C6FY3mwEJ6fnI9RRGQ","not-before-policy":0,"session_state":"fd1dfa4b-5306-4095-a37d-64c6122de3b2","scope":"openid + email profile kvk bsn"}' + headers: + Cache-Control: + - no-store + Content-Type: + - application/json + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '3614' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/certs + response: + body: + string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;charset=UTF-8 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '2909' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Authorization: + - Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjI1NDc4ODMsImlhdCI6MTcyMjU0NzU4MywiYXV0aF90aW1lIjoxNzIyNTQ3NTgzLCJqdGkiOiJmYjU0NmI1Mi0wMDcyLTQ3M2UtYWVmYS03MTcwMjMzZjljOTciLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMTM1NmMyYzItMDFlMC00MjhlLThmOTMtOWEwZGQ4Yzk1M2ZmIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6ImZkMWRmYTRiLTUzMDYtNDA5NS1hMzdkLTY0YzYxMjJkZTNiMiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgYnNuIiwic2lkIjoiZmQxZGZhNGItNTMwNi00MDk1LWEzN2QtNjRjNjEyMmRlM2IyIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJhZG1pbiBhZG1pbiIsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6ImFkbWluIiwiZmFtaWx5X25hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AYWRtaW4uYWRtaW4ifQ.in3vUi9Ml3XQSZ74DMDYUeLIjkcwmxl6r2yL0TSHfATYicjkLjx4YPyicF8NdgiXSHgjoz-zRYMqvNLmcV5gs-pNfLQ0D5hlEvv0UYEM5KsJe6x_FWqUKXkldeHl5L0TUIdzWrkJWLSzxdkK0hjbLVbqPG9JHf7V0OJyQcRF4syXoHj5CAXDn1IThVGN4WojkQwZAiv_CWYOlVVDlCU5cRP68pszf32K4ePkPVkl-YrBxJ9ZYoOofLEWe0PSjActdpjnsRKRQW5Vs0pjLsFnt7yX20NrvzH_lQy25wZArhYS4NL7UgZqugsIyCulzXoedNv-J655_gQSoq52utIkww + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/userinfo + response: + body: + string: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJzdWIiOiIxMzU2YzJjMi0wMWUwLTQyOGUtOGY5My05YTBkZDhjOTUzZmYiLCJhdWQiOiJ0ZXN0aWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6ImFkbWluIGFkbWluIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJnaXZlbl9uYW1lIjoiYWRtaW4iLCJmYW1pbHlfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBhZG1pbi5hZG1pbiJ9.s6mDhNLibfQz8GoNzdK1kxI1PtBOkoggYnDXflARWYnhztZucIhz77SrUu9e7rfyYdQZhNEAYu43MBeaUl9Z7ITf0qKrwruju54i51dwRcLxchu86SNxgmoDDj8000un4tpV-y6YTZ_QsaLevkTFhsT0OOv6mvzHvbu7AmJSQMnGNj4IZlvEc-8aJ-5dxGXNfdcyJeqVVB85j_M4SHNsYT2qLrU5A3oTL7g6h05l5Ex8MQ-uNCCDHBWSwmlfKwzyJiTtJS8TKwMiQnVYpebSuKhA36dXQd72DuaxQmejZodzrtXStS6w3yYAgUyIAfVdf7S5peLygs2IVqf_UNohzQ + headers: + Cache-Control: + - no-cache + Content-Type: + - application/jwt + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-XSS-Protection: + - 1; mode=block + content-length: + - '783' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/certs + response: + body: + string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;charset=UTF-8 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '2909' + status: + code: 200 + message: OK +version: 1 diff --git a/src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml b/src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml new file mode 100644 index 00000000..fd490802 --- /dev/null +++ b/src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml @@ -0,0 +1,314 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=testid&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F&state=not-a-random-string&nonce=not-a-random-string + response: + body: + string: "\n\n\n\n \n + \ \n \n\n \n Sign + in to test\n \n \n \n \n \n \n \n\n\n\n
\n + \
\n
test
\n
\n
\n + \
\n

+ \ Sign in to your account\n\n

\n
\n
\n + \
\n\n\n
\n + \
\n
\n
\n \n\n \n\n\n
\n\n
\n \n\n
\n + \ \n \n + \
\n\n\n
\n\n
\n
\n + \
\n
\n + \
\n\n
\n\n
\n \n \n
\n + \
\n
\n
\n \n\n\n\n\n\n + \
\n
\n\n
\n
\n\n\n" + headers: + Cache-Control: + - no-store, must-revalidate, max-age=0 + Content-Language: + - en + Content-Security-Policy: + - frame-src 'self'; frame-ancestors 'self'; object-src 'none'; + Content-Type: + - text/html;charset=utf-8 + Referrer-Policy: + - no-referrer + Set-Cookie: + - AUTH_SESSION_ID=4d37b9ff-7840-4c0e-ae54-61797c065617; Version=1; Path=/realms/test/; + SameSite=None; Secure; HttpOnly + - AUTH_SESSION_ID_LEGACY=4d37b9ff-7840-4c0e-ae54-61797c065617; Version=1; Path=/realms/test/; + HttpOnly + - KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI; + Version=1; Path=/realms/test/; HttpOnly + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Robots-Tag: + - none + X-XSS-Protection: + - 1; mode=block + content-length: + - '4466' + status: + code: 200 + message: OK +- request: + body: username=admin&password=admin&credentialId=&login=Sign+In + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + Content-Length: + - '57' + Content-Type: + - application/x-www-form-urlencoded + Cookie: + - AUTH_SESSION_ID_LEGACY=4d37b9ff-7840-4c0e-ae54-61797c065617; KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8080/realms/test/login-actions/authenticate?session_code=4l-JY6BOiZ8bacQRJjI1QXUfbJ3HXTqG6qkCFLdKlQA&execution=670fb55e-641e-4beb-bd17-3c0cb001b805&client_id=testid&tab_id=mi2knizGlJM + response: + body: + string: '' + headers: + Cache-Control: + - no-store, must-revalidate, max-age=0 + Content-Security-Policy: + - frame-src 'self'; frame-ancestors 'self'; object-src 'none'; + Location: + - http://testserver/oidc/callback/?state=not-a-random-string&session_state=4d37b9ff-7840-4c0e-ae54-61797c065617&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Ftest&code=79d14c65-ffcd-4066-8cbe-98423d3b0f9d.4d37b9ff-7840-4c0e-ae54-61797c065617.adf4ad83-4550-4619-9231-73bd8d700f45 + Referrer-Policy: + - no-referrer + Set-Cookie: + - KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 + 00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly + - KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; + Path=/realms/test/; HttpOnly + - KC_AUTH_STATE=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; + Path=/realms/test/ + - KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjAxNTU4MzMsImlhdCI6MTcyMDExOTgzMywianRpIjoiOGRhYzBkZTItMGMzMC00NWNkLWI2NTctMjA2OGRlZjU2ZGU1IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJzaWQiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJzdGF0ZV9jaGVja2VyIjoiS29jaEZHYjRwU1hLVHl4ZTFhdUtCUDhnYmZPWWxGNnNKNFJZRmJ1ZmI3ZyJ9.B9lZZIe-jlw3iAIJi3ZLoho2-rGpYn7X86-xzwPgBUk; + Version=1; Path=/realms/test/; SameSite=None; Secure; HttpOnly + - KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjAxNTU4MzMsImlhdCI6MTcyMDExOTgzMywianRpIjoiOGRhYzBkZTItMGMzMC00NWNkLWI2NTctMjA2OGRlZjU2ZGU1IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJzaWQiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJzdGF0ZV9jaGVja2VyIjoiS29jaEZHYjRwU1hLVHl4ZTFhdUtCUDhnYmZPWWxGNnNKNFJZRmJ1ZmI3ZyJ9.B9lZZIe-jlw3iAIJi3ZLoho2-rGpYn7X86-xzwPgBUk; + Version=1; Path=/realms/test/; HttpOnly + - KEYCLOAK_SESSION=test/6db2db87-de31-4e30-9f25-cefe5da8b154/4d37b9ff-7840-4c0e-ae54-61797c065617; + Version=1; Expires=Fri, 05-Jul-2024 05:03:53 GMT; Max-Age=36000; Path=/realms/test/; + SameSite=None; Secure + - KEYCLOAK_SESSION_LEGACY=test/6db2db87-de31-4e30-9f25-cefe5da8b154/4d37b9ff-7840-4c0e-ae54-61797c065617; + Version=1; Expires=Fri, 05-Jul-2024 05:03:53 GMT; Max-Age=36000; Path=/realms/test/ + - KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 + 00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Robots-Tag: + - none + X-XSS-Protection: + - 1; mode=block + content-length: + - '0' + status: + code: 302 + message: Found +- request: + body: client_id=testid&client_secret=7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I&grant_type=authorization_code&code=79d14c65-ffcd-4066-8cbe-98423d3b0f9d.4d37b9ff-7840-4c0e-ae54-61797c065617.adf4ad83-4550-4619-9231-73bd8d700f45&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + Content-Length: + - '267' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8080/realms/test/protocol/openid-connect/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjAxMjAxMzMsImlhdCI6MTcyMDExOTgzMywiYXV0aF90aW1lIjoxNzIwMTE5ODMzLCJqdGkiOiIzNjZlNDJmOS01ZTdjLTQ0N2YtYTExMS1kYzBmZGU4NTAyMjciLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjRkMzdiOWZmLTc4NDAtNGMwZS1hZTU0LTYxNzk3YzA2NTYxNyIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6IjRkMzdiOWZmLTc4NDAtNGMwZS1hZTU0LTYxNzk3YzA2NTYxNyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.pLHSN-f0pCdn1Rqy9-nAPqVFeJjPRElkySwfXTvBKHkgSqqCf3eo3IoDluU4rmlIE4wXi4GpeusADlru_jc76zeDUi5haMUtHNQ2m70tl31DTP4DnfV7jppoIq2n_CMDfwhqP9zG-d2QNznPSa5aIaXHGmD48LnbeLlgue5a2Y1Zljg6r0GZJY-9dm3W4n_pgTt-254gsSh_sxbo42OZEUk4Pq0dAzzW4SZ72r0SxzFA9WC1w_-L3kaZ6Ohe1p9ZaizzccKikIq1mEc0tSEgBardNDhwSMIBNTCnfuojIiiU7ro9u8_1TT_BKgNmEm3QhyMdRw3IBMUzYCSPNmaAow","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjAxMjE2MzMsImlhdCI6MTcyMDExOTgzMywianRpIjoiMjRhYWU3ZTQtMDk5Mi00MmJkLWI1MGItNmVmNjY4Zjk1ZjEwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIGt2ayBncm91cHMgYnNuIiwic2lkIjoiNGQzN2I5ZmYtNzg0MC00YzBlLWFlNTQtNjE3OTdjMDY1NjE3In0.xB2_pY-y-_70SgH4xDxR02SjaYglIKTgP6Wz7t6SIW0","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjAxMjAxMzMsImlhdCI6MTcyMDExOTgzMywiYXV0aF90aW1lIjoxNzIwMTE5ODMzLCJqdGkiOiIwZmVhODkwYS1jYWUxLTRhMTItYmQ4Yi05MWIzZjIzZWU3MmYiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJ0ZXN0aWQiLCJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJ0eXAiOiJJRCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJhdF9oYXNoIjoiUTJTZ3phYWNhM1JQWHZfZ05qU3BQUSIsImFjciI6IjEiLCJzaWQiOiI0ZDM3YjlmZi03ODQwLTRjMGUtYWU1NC02MTc5N2MwNjU2MTciLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.copggZp0m60QmYfo4cjtiRNbvOsYg_LhT-qVH2zCkhlIFN4GQvx46uLY-u5AL1wQHXDhL708h8ZfQNSY3ZVh3I-gPn-h3uKiL5bwyfdXX_9XHCOh8KfeMTuXJLgJF-ebzP41i7un1Wjsi8StlL-uTkrKxWjG0BIUwmhU6z5UqGFQvg5US83mpFWhtPN_BkBC2IWZDtGthjBhGBxzdPCYpAsfZsQuZpzIHkdcqw1-mjjVwmPDfma8q2-MgweL9zpbmAgbdzPUx8byHuJFir3gtnU5liS4Yy_DmsRr51c43cH_7wtmH_6aLAxe6f5srZ9BbNZ2XD016Wj8x1xLEY9k8Q","not-before-policy":0,"session_state":"4d37b9ff-7840-4c0e-ae54-61797c065617","scope":"openid + email profile kvk groups bsn"}' + headers: + Cache-Control: + - no-store + Content-Type: + - application/json + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '3698' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/certs + response: + body: + string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;charset=UTF-8 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '2909' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Authorization: + - Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjAxMjAxMzMsImlhdCI6MTcyMDExOTgzMywiYXV0aF90aW1lIjoxNzIwMTE5ODMzLCJqdGkiOiIzNjZlNDJmOS01ZTdjLTQ0N2YtYTExMS1kYzBmZGU4NTAyMjciLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjRkMzdiOWZmLTc4NDAtNGMwZS1hZTU0LTYxNzk3YzA2NTYxNyIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6IjRkMzdiOWZmLTc4NDAtNGMwZS1hZTU0LTYxNzk3YzA2NTYxNyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.pLHSN-f0pCdn1Rqy9-nAPqVFeJjPRElkySwfXTvBKHkgSqqCf3eo3IoDluU4rmlIE4wXi4GpeusADlru_jc76zeDUi5haMUtHNQ2m70tl31DTP4DnfV7jppoIq2n_CMDfwhqP9zG-d2QNznPSa5aIaXHGmD48LnbeLlgue5a2Y1Zljg6r0GZJY-9dm3W4n_pgTt-254gsSh_sxbo42OZEUk4Pq0dAzzW4SZ72r0SxzFA9WC1w_-L3kaZ6Ohe1p9ZaizzccKikIq1mEc0tSEgBardNDhwSMIBNTCnfuojIiiU7ro9u8_1TT_BKgNmEm3QhyMdRw3IBMUzYCSPNmaAow + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/userinfo + response: + body: + string: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJhdWQiOiJ0ZXN0aWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.vx4dCJ-Y-PEzjy8p7CNPB3yy0TyV_QugOHRbiV6UY3qHtZUnZqSsJD991QUostcYECuyTHefqfRtdCbvSJcPWI4ucosY65vshUMBtQeahsFOgNwWp2BvCkALJmEya4H_gh63vVlVZ2ZOSpWpah6eV2PNhiiYWD-Y9qEuLMzwngNvp5hna30BiRKAEsStB7izjE5pGECqkQm7pxCeZWHU81Lbh5fSo_2XvcGZ1Z-tf6DN95Oz4ers9YrG6dKSuh-HciY1zhv7mcee_tlJaeKjITue6r06163oKdjsYKRpiR4bLQ9256KafoxmU6O0IIlpkQhmtXrmaFSg0XyBYU8qcQ + headers: + Cache-Control: + - no-cache + Content-Type: + - application/jwt + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-XSS-Protection: + - 1; mode=block + content-length: + - '813' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8080/realms/test/protocol/openid-connect/certs + response: + body: + string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;charset=UTF-8 + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - 1; mode=block + content-length: + - '2909' + status: + code: 200 + message: OK +version: 1 diff --git a/src/objects/accounts/tests/test_oidc.py b/src/objects/accounts/tests/test_oidc.py index b677f192..9eaa0732 100644 --- a/src/objects/accounts/tests/test_oidc.py +++ b/src/objects/accounts/tests/test_oidc.py @@ -1,9 +1,30 @@ +from functools import partial +from pathlib import Path + from django.urls import reverse from django.utils.translation import gettext as _ +import vcr from django_webtest import WebTest from mozilla_django_oidc_db.models import OpenIDConnectConfig +from objects.utils.tests.keycloak import keycloak_login, mock_oidc_db_config + +from ..models import User +from .factories import StaffUserFactory + +TEST_FILES = (Path(__file__).parent / "keycloak_cassets").resolve() + + +mock_admin_oidc_config = partial( + mock_oidc_db_config, + app_label="mozilla_django_oidc_db", + model="OpenIDConnectConfig", + id=1, # required for the group queries because we're using in-memory objects + make_users_staff=True, + username_claim=["preferred_username"], +) + class OIDCLoginButtonTestCase(WebTest): def test_oidc_button_disabled(self): @@ -40,3 +61,86 @@ def test_oidc_button_enabled(self): self.assertEqual( oidc_login_link.attrs["href"], reverse("oidc_authentication_init") ) + + +class OIDCFLowTests(WebTest): + @vcr.use_cassette(str(TEST_FILES / "duplicate_email.yaml")) + @mock_admin_oidc_config() + def test_duplicate_email_unique_constraint_violated(self): + # this user collides on the email address + staff_user = StaffUserFactory.create( + username="no-match", email="admin@example.com" + ) + login_page = self.app.get(reverse("admin:login")) + start_response = login_page.click( + description=_("Login with organization account") + ) + assert start_response.status_code == 302 + redirect_uri = keycloak_login( + start_response["Location"], username="admin", password="admin" + ) + + error_page = self.app.get(redirect_uri, auto_follow=True) + + with self.subTest("error page"): + self.assertEqual(error_page.status_code, 200) + self.assertEqual(error_page.request.path, reverse("admin-oidc-error")) + self.assertEqual( + error_page.context["oidc_error"], + 'duplicate key value violates unique constraint "filled_email_unique"\n' + "DETAIL: Key (email)=(admin@example.com) already exists.\n", + ) + self.assertContains( + error_page, "duplicate key value violates unique constraint" + ) + + with self.subTest("user state unmodified"): + self.assertEqual(User.objects.count(), 1) + staff_user.refresh_from_db() + self.assertEqual(staff_user.username, "no-match") + self.assertEqual(staff_user.email, "admin@example.com") + self.assertTrue(staff_user.is_staff) + + @vcr.use_cassette(str(TEST_FILES / "happy_flow.yaml")) + @mock_admin_oidc_config() + def test_happy_flow(self): + login_page = self.app.get(reverse("admin:login")) + start_response = login_page.click( + description=_("Login with organization account") + ) + assert start_response.status_code == 302 + redirect_uri = keycloak_login( + start_response["Location"], username="admin", password="admin" + ) + + admin_index = self.app.get(redirect_uri, auto_follow=True) + + self.assertEqual(admin_index.status_code, 200) + self.assertEqual(admin_index.request.path, reverse("admin:index")) + + self.assertEqual(User.objects.count(), 1) + user = User.objects.get() + self.assertEqual(user.username, "admin") + + @vcr.use_cassette(str(TEST_FILES / "happy_flow_existing_user.yaml")) + @mock_admin_oidc_config(make_users_staff=False) + def test_happy_flow_existing_user(self): + staff_user = StaffUserFactory.create(username="admin", email="update-me") + login_page = self.app.get(reverse("admin:login")) + start_response = login_page.click( + description=_("Login with organization account") + ) + assert start_response.status_code == 302 + redirect_uri = keycloak_login( + start_response["Location"], username="admin", password="admin" + ) + + admin_index = self.app.get(redirect_uri, auto_follow=True) + + self.assertEqual(admin_index.status_code, 200) + self.assertEqual(admin_index.request.path, reverse("admin:index")) + + self.assertEqual(User.objects.count(), 1) + staff_user.refresh_from_db() + self.assertEqual(staff_user.username, "admin") + self.assertEqual(staff_user.email, "admin@example.com") diff --git a/src/objects/api/v2/openapi.yaml b/src/objects/api/v2/openapi.yaml index fc9aa086..c5315589 100644 --- a/src/objects/api/v2/openapi.yaml +++ b/src/objects/api/v2/openapi.yaml @@ -934,6 +934,9 @@ components: $ref: '#/components/schemas/GeoWithin' PaginatedHistoryRecordList: type: object + required: + - count + - results properties: count: type: integer @@ -954,6 +957,9 @@ components: $ref: '#/components/schemas/HistoryRecord' PaginatedObjectList: type: object + required: + - count + - results properties: count: type: integer @@ -974,6 +980,9 @@ components: $ref: '#/components/schemas/Object' PaginatedPermissionList: type: object + required: + - count + - results properties: count: type: integer diff --git a/src/objects/conf/base.py b/src/objects/conf/base.py index 686459cc..8ab45a50 100644 --- a/src/objects/conf/base.py +++ b/src/objects/conf/base.py @@ -66,6 +66,16 @@ "objects.utils.admin_index.should_display_dropdown_menu" ) +# +# MAYKIN-2FA +# +# It uses django-two-factor-auth under the hood so you can configure +# those settings too. +# +# we run the admin site monkeypatch instead. +# Relying Party name for WebAuthn (hardware tokens) +TWO_FACTOR_WEBAUTHN_RP_NAME = "objects api" + # VNG API Common CUSTOM_CLIENT_FETCHER = "objects.utils.client.get_client" diff --git a/src/objects/tests/commands/test_setup_configuration.py b/src/objects/tests/commands/test_setup_configuration.py index 5a0d06e6..5ba3add9 100644 --- a/src/objects/tests/commands/test_setup_configuration.py +++ b/src/objects/tests/commands/test_setup_configuration.py @@ -57,7 +57,7 @@ def test_setup_configuration(self, m): f"{ObjecttypesStep()} is successfully configured", f"Configuring {DemoUserStep()}...", f"{DemoUserStep()} is successfully configured", - "Instance configuration completed.", + f"Instance configuration completed.", ] self.assertEqual(command_output, expected_output) diff --git a/src/objects/urls.py b/src/objects/urls.py index e54bba45..74647f37 100644 --- a/src/objects/urls.py +++ b/src/objects/urls.py @@ -9,6 +9,7 @@ from maykin_2fa import monkeypatch_admin from maykin_2fa.urls import urlpatterns as maykin_2fa_urlpatterns, webauthn_urlpatterns +from mozilla_django_oidc_db.views import AdminLoginFailure from rest_framework.settings import api_settings handler500 = "objects.utils.views.server_error" @@ -29,6 +30,7 @@ auth_views.PasswordResetDoneView.as_view(), name="password_reset_done", ), + path("admin/login/failure/", AdminLoginFailure.as_view(), name="admin-oidc-error"), path("admin/", include((maykin_2fa_urlpatterns, "maykin_2fa"))), path("admin/", include((webauthn_urlpatterns, "two_factor"))), path("admin/", admin.site.urls), diff --git a/src/objects/utils/tests/__init__.py b/src/objects/utils/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/objects/utils/tests/keycloak.py b/src/objects/utils/tests/keycloak.py new file mode 100644 index 00000000..73633ed6 --- /dev/null +++ b/src/objects/utils/tests/keycloak.py @@ -0,0 +1,89 @@ +from contextlib import contextmanager, nullcontext +from unittest.mock import patch + +from django.apps import apps + +from pyquery import PyQuery as pq +from requests import Session + +KEYCLOAK_BASE_URL = "http://localhost:8080/realms/test/protocol/openid-connect" + + +def keycloak_login( + login_url: str, + username: str = "testuser", + password: str = "testuser", + host: str = "http://testserver/", + session: Session | None = None, +) -> str: + """ + Test helper to perform a keycloak login. + + :param login_url: A login URL for keycloak with all query string parameters. E.g. + `client.get(reverse("login"))["Location"]`. + :returns: The redirect URI to consume in the django application, with the ``code`` + ``state`` query parameters. Consume this with ``response = client.get(url)``. + """ + cm = Session() if session is None else nullcontext(session) + with cm as session: + login_page = session.get(login_url) + assert login_page.status_code == 200 + + # process keycloak's login form and submit the username + password to + # authenticate + document = pq(login_page.text) + login_form = document("form#kc-form-login") + submit_url = login_form.attr("action") + assert isinstance(submit_url, str) + login_response = session.post( + submit_url, + data={ + "username": username, + "password": password, + "credentialId": "", + "login": "Sign In", + }, + allow_redirects=False, + ) + + assert login_response.status_code == 302 + assert (redirect_uri := login_response.headers["Location"]).startswith(host) + + return redirect_uri + + +@contextmanager +def mock_oidc_db_config(app_label: str, model: str, **overrides): + """ + Bundle all the required mocks. + + This context manager deliberately prevents the mocked things from being injected in + the test method signature. + """ + defaults = { + "enabled": True, + "oidc_rp_client_id": "testid", + "oidc_rp_client_secret": "7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I", + "oidc_rp_sign_algo": "RS256", + "oidc_rp_scopes_list": ["openid"], + "oidc_op_jwks_endpoint": f"{KEYCLOAK_BASE_URL}/certs", + "oidc_op_authorization_endpoint": f"{KEYCLOAK_BASE_URL}/auth", + "oidc_op_token_endpoint": f"{KEYCLOAK_BASE_URL}/token", + "oidc_op_user_endpoint": f"{KEYCLOAK_BASE_URL}/userinfo", + } + field_values = {**defaults, **overrides} + model_cls = apps.get_model(app_label, model) + with ( + # bypass django-solo queries + cache hits + patch( + f"{model_cls.__module__}.{model}.get_solo", + return_value=model_cls(**field_values), + ), + # mock the state & nonce random value generation so we get predictable URLs to + # match with VCR + patch( + "mozilla_django_oidc.views.get_random_string", + return_value="not-a-random-string", + ), + ): + yield