diff --git a/package-lock.json b/package-lock.json
index 41e56bef..9186ecbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
"packages": {
"": {
"name": "objecttypes",
- "version": "2.1.2",
+ "version": "2.2.0",
"license": "EUPL",
"dependencies": {
"microscope-sass": "latest"
@@ -2770,11 +2770,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"
@@ -3902,9 +3902,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",
@@ -3916,7 +3916,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"
@@ -4158,17 +4158,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",
@@ -4199,34 +4199,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"
@@ -4271,21 +4247,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",
@@ -4463,9 +4424,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"
},
@@ -4566,9 +4527,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": [
{
@@ -8576,12 +8537,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": {
@@ -9496,9 +9458,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",
@@ -9577,27 +9539,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",
@@ -9784,16 +9725,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 8413704b..013ff217 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
@@ -11,6 +11,7 @@ ape-pie==0.1.0
asgiref==3.6.0
# via
# django
+ # django-axes
# django-cors-headers
asn1crypto==1.5.1
# via webauthn
@@ -20,7 +21,7 @@ attrs==23.1.0
# via
# glom
# jsonschema
-billiard==3.6.4.0
+billiard==4.2.0
# via celery
bleach==6.1.0
# via open-api-framework
@@ -30,12 +31,12 @@ boltons==23.0.0
# glom
cbor2==5.6.3
# via webauthn
-celery==5.2.7
+celery==5.4.0
# via
# flower
# notifications-api-common
# open-api-framework
-certifi==2024.2.2
+certifi==2024.07.04
# via
# elastic-apm
# requests
@@ -69,7 +70,7 @@ cryptography==42.0.7
# mozilla-django-oidc
# pyopenssl
# webauthn
-django==4.2.11
+django==4.2.14
# via
# commonground-api-common
# django-admin-index
@@ -109,17 +110,17 @@ django-admin-index==3.1.1
# via open-api-framework
django-appconf==1.0.6
# via django-log-outgoing-requests
-django-axes==6.4.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.2
+django-filter==24.2
# via
# commonground-api-common
# open-api-framework
django-formtools==2.4.1
# via django-two-factor-auth
-django-jsonform==2.21.5
+django-jsonform==2.22.0
# via
# mozilla-django-oidc-db
# open-api-framework
@@ -161,7 +162,7 @@ django-solo==2.0.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
@@ -231,15 +232,15 @@ kombu==5.3.5
# via celery
markupsafe==2.1.2
# 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.16.0
+mozilla-django-oidc-db==0.19.0
# via open-api-framework
notifications-api-common==0.2.2
# via 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
@@ -269,15 +270,15 @@ pyopenssl==24.0.0
pyrsistent==0.19.3
# via jsonschema
python-dateutil==2.8.2
- # via django-relativedelta
+ # via
+ # celery
+ # django-relativedelta
python-decouple==3.8
# via open-api-framework
python-dotenv==1.0.0
# via open-api-framework
pytz==2023.3
# via
- # celery
- # djangorestframework
# drf-yasg
# flower
pyyaml==6.0
@@ -290,7 +291,7 @@ qrcode==6.1
# via django-two-factor-auth
redis==4.5.5
# via django-redis
-requests==2.31.0
+requests==2.32.3
# via
# ape-pie
# commonground-api-common
@@ -301,7 +302,7 @@ requests==2.31.0
# open-api-framework
# sharing-configs
# zgw-consumers
-sentry-sdk==1.45.0
+sentry-sdk==2.12.0
# via open-api-framework
sharing-configs==0.1.2
# via -r requirements/base.in
@@ -316,23 +317,27 @@ six==1.16.0
# qrcode
sqlparse==0.5.0
# via django
-tornado==6.4
+tornado==6.4.1
# via flower
typing-extensions==4.11.0
- # via zgw-consumers
+ # via
+ # mozilla-django-oidc-db
+ # zgw-consumers
+tzdata==2024.1
+ # via celery
uritemplate==4.1.1
# via
# coreapi
# drf-spectacular
# drf-yasg
-urllib3==2.2.1
+urllib3==2.2.2
# via
# elastic-apm
# requests
# sentry-sdk
uwsgi==2.0.24
# via open-api-framework
-vine==5.0.0
+vine==5.1.0
# via
# amqp
# celery
diff --git a/requirements/ci.txt b/requirements/ci.txt
index 7b96e938..114232be 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
@@ -16,6 +16,7 @@ asgiref==3.6.0
# via
# -r requirements/base.txt
# django
+ # django-axes
# django-cors-headers
asn1crypto==1.5.1
# via
@@ -32,7 +33,7 @@ attrs==23.1.0
# jsonschema
beautifulsoup4==4.12.2
# via webtest
-billiard==3.6.4.0
+billiard==4.2.0
# via
# -r requirements/base.txt
# celery
@@ -49,13 +50,13 @@ cbor2==5.6.3
# 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==2024.2.2
+certifi==2024.07.04
# via
# -r requirements/base.txt
# elastic-apm
@@ -112,7 +113,7 @@ cryptography==42.0.7
# webauthn
cssselect==1.2.0
# via pyquery
-django==4.2.11
+django==4.2.14
# via
# -r requirements/base.txt
# commonground-api-common
@@ -158,15 +159,15 @@ django-appconf==1.0.6
# via
# -r requirements/base.txt
# django-log-outgoing-requests
-django-axes==6.4.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.2
+django-filter==24.2
# via
# -r requirements/base.txt
# commonground-api-common
@@ -177,7 +178,7 @@ django-formtools==2.4.1
# django-two-factor-auth
django-jenkins==0.110.0
# via -r requirements/test-tools.in
-django-jsonform==2.21.5
+django-jsonform==2.22.0
# via
# -r requirements/base.txt
# mozilla-django-oidc-db
@@ -247,7 +248,7 @@ django-two-factor-auth[phonenumberslite,webauthn]==1.16.0
# maykin-2fa
django-webtest==1.9.10
# via -r requirements/test-tools.in
-djangorestframework==3.14.0
+djangorestframework==3.15.2
# via
# -r requirements/base.txt
# commonground-api-common
@@ -326,6 +327,7 @@ idna==3.7
# via
# -r requirements/base.txt
# requests
+ # yarl
inflection==0.5.1
# via
# -r requirements/base.txt
@@ -365,7 +367,7 @@ markupsafe==2.1.2
# via
# -r requirements/base.txt
# jinja2
-maykin-2fa==1.0.0
+maykin-2fa==1.0.1
# via
# -r requirements/base.txt
# open-api-framework
@@ -373,15 +375,17 @@ mozilla-django-oidc==4.0.0
# via
# -r requirements/base.txt
# mozilla-django-oidc-db
-mozilla-django-oidc-db==0.16.0
+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
@@ -435,6 +439,7 @@ pyrsistent==0.19.3
python-dateutil==2.8.2
# via
# -r requirements/base.txt
+ # celery
# django-relativedelta
# faker
# freezegun
@@ -449,8 +454,6 @@ python-dotenv==1.0.0
pytz==2023.3
# via
# -r requirements/base.txt
- # celery
- # djangorestframework
# drf-yasg
# flower
pyyaml==6.0
@@ -460,6 +463,7 @@ pyyaml==6.0
# drf-yasg
# gemma-zds-client
# oyaml
+ # vcrpy
qrcode==6.1
# via
# -r requirements/base.txt
@@ -468,7 +472,7 @@ redis==4.5.5
# via
# -r requirements/base.txt
# django-redis
-requests==2.31.0
+requests==2.32.3
# via
# -r requirements/base.txt
# ape-pie
@@ -483,7 +487,7 @@ requests==2.31.0
# zgw-consumers
requests-mock==1.10.0
# via -r requirements/test-tools.in
-sentry-sdk==1.45.0
+sentry-sdk==2.12.0
# via
# -r requirements/base.txt
# open-api-framework
@@ -508,21 +512,26 @@ sqlparse==0.5.0
# django
tblib==1.7.0
# via -r requirements/test-tools.in
-tornado==6.4
+tornado==6.4.1
# via
# -r requirements/base.txt
# flower
typing-extensions==4.11.0
# via
# -r requirements/base.txt
+ # mozilla-django-oidc-db
# zgw-consumers
+tzdata==2024.1
+ # via
+ # -r requirements/base.txt
+ # celery
uritemplate==4.1.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
@@ -532,7 +541,9 @@ uwsgi==2.0.24
# via
# -r requirements/base.txt
# open-api-framework
-vine==5.0.0
+vcrpy==6.0.1
+ # via -r requirements/test-tools.in
+vine==5.1.0
# via
# -r requirements/base.txt
# amqp
@@ -560,6 +571,9 @@ wrapt==1.14.1
# via
# -r requirements/base.txt
# elastic-apm
+ # vcrpy
+yarl==1.9.4
+ # via vcrpy
zgw-consumers==0.33.0
# via
# -r requirements/base.txt
diff --git a/requirements/dev.txt b/requirements/dev.txt
index 3a666700..011a193e 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
@@ -18,6 +18,7 @@ asgiref==3.6.0
# via
# -r requirements/ci.txt
# django
+ # django-axes
# django-cors-headers
asn1crypto==1.5.1
# via
@@ -38,7 +39,7 @@ beautifulsoup4==4.12.2
# via
# -r requirements/ci.txt
# webtest
-billiard==3.6.4.0
+billiard==4.2.0
# via
# -r requirements/ci.txt
# celery
@@ -63,13 +64,13 @@ cbor2==5.6.3
# 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==2024.2.2
+certifi==2024.07.04
# via
# -r requirements/ci.txt
# elastic-apm
@@ -130,7 +131,7 @@ cssselect==1.2.0
# via
# -r requirements/ci.txt
# pyquery
-django==4.2.11
+django==4.2.14
# via
# -r requirements/ci.txt
# commonground-api-common
@@ -178,11 +179,11 @@ django-appconf==1.0.6
# via
# -r requirements/ci.txt
# django-log-outgoing-requests
-django-axes==6.4.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
@@ -190,7 +191,7 @@ django-debug-toolbar==4.1.0
# via -r requirements/dev.in
django-extensions==3.2.1
# via -r requirements/dev.in
-django-filter==23.2
+django-filter==24.2
# via
# -r requirements/ci.txt
# commonground-api-common
@@ -201,7 +202,7 @@ django-formtools==2.4.1
# django-two-factor-auth
django-jenkins==0.110.0
# via -r requirements/ci.txt
-django-jsonform==2.21.5
+django-jsonform==2.22.0
# via
# -r requirements/ci.txt
# mozilla-django-oidc-db
@@ -271,7 +272,7 @@ django-two-factor-auth[phonenumberslite,webauthn]==1.16.0
# maykin-2fa
django-webtest==1.9.10
# via -r requirements/ci.txt
-djangorestframework==3.14.0
+djangorestframework==3.15.2
# via
# -r requirements/ci.txt
# commonground-api-common
@@ -358,6 +359,7 @@ idna==3.7
# via
# -r requirements/ci.txt
# requests
+ # yarl
imagesize==1.4.1
# via sphinx
inflection==0.5.1
@@ -404,7 +406,7 @@ markupsafe==2.1.2
# via
# -r requirements/ci.txt
# jinja2
-maykin-2fa==1.0.0
+maykin-2fa==1.0.1
# via
# -r requirements/ci.txt
# open-api-framework
@@ -414,17 +416,21 @@ mozilla-django-oidc==4.0.0
# via
# -r requirements/ci.txt
# mozilla-django-oidc-db
-mozilla-django-oidc-db==0.16.0
+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==1.0.0
# 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
@@ -447,7 +453,7 @@ phonenumberslite==8.13.30
# via
# -r requirements/ci.txt
# django-two-factor-auth
-pip-tools==6.13.0
+pip-tools==7.3.0
# via -r requirements/dev.in
platformdirs==3.5.1
# via black
@@ -495,6 +501,7 @@ pyrsistent==0.19.3
python-dateutil==2.8.2
# via
# -r requirements/ci.txt
+ # celery
# django-relativedelta
# faker
# freezegun
@@ -509,8 +516,6 @@ python-dotenv==1.0.0
pytz==2023.3
# via
# -r requirements/ci.txt
- # celery
- # djangorestframework
# drf-yasg
# flower
pyyaml==6.0
@@ -520,6 +525,7 @@ pyyaml==6.0
# drf-yasg
# gemma-zds-client
# oyaml
+ # vcrpy
qrcode==6.1
# via
# -r requirements/ci.txt
@@ -528,7 +534,7 @@ redis==4.5.5
# via
# -r requirements/ci.txt
# django-redis
-requests==2.31.0
+requests==2.32.3
# via
# -r requirements/ci.txt
# ape-pie
@@ -544,7 +550,7 @@ requests==2.31.0
# zgw-consumers
requests-mock==1.10.0
# via -r requirements/ci.txt
-sentry-sdk==1.45.0
+sentry-sdk==2.12.0
# via
# -r requirements/ci.txt
# open-api-framework
@@ -595,26 +601,26 @@ sqlparse==0.5.0
# django-debug-toolbar
tblib==1.7.0
# via -r requirements/ci.txt
-tomli==2.0.1
- # via
- # black
- # build
-tornado==6.4
+tornado==6.4.1
# via
# -r requirements/ci.txt
# flower
typing-extensions==4.11.0
# via
# -r requirements/ci.txt
- # black
+ # mozilla-django-oidc-db
# zgw-consumers
+tzdata==2024.1
+ # via
+ # -r requirements/ci.txt
+ # celery
uritemplate==4.1.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
@@ -624,7 +630,9 @@ uwsgi==2.0.24
# via
# -r requirements/ci.txt
# open-api-framework
-vine==5.0.0
+vcrpy==6.0.1
+ # via -r requirements/ci.txt
+vine==5.1.0
# via
# -r requirements/ci.txt
# amqp
@@ -660,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.33.0
# via
# -r requirements/ci.txt
diff --git a/requirements/test-tools.in b/requirements/test-tools.in
index f890456f..37839e73 100644
--- a/requirements/test-tools.in
+++ b/requirements/test-tools.in
@@ -7,3 +7,4 @@ freezegun
pyquery # integrates with webtest
requests-mock
tblib
+vcrpy
diff --git a/src/objecttypes/accounts/tests/factories.py b/src/objecttypes/accounts/tests/factories.py
index 1ce3f69c..dfad0ea1 100644
--- a/src/objecttypes/accounts/tests/factories.py
+++ b/src/objecttypes/accounts/tests/factories.py
@@ -1,11 +1,29 @@
+from django.contrib.auth import get_user_model
+
import factory
+from factory.django import DjangoModelFactory
+
+User = get_user_model()
-class UserFactory(factory.django.DjangoModelFactory):
+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
class SuperUserFactory(UserFactory):
diff --git a/src/objecttypes/accounts/tests/keycloak_cassets/duplicate_email.yaml b/src/objecttypes/accounts/tests/keycloak_cassets/duplicate_email.yaml
new file mode 100644
index 00000000..a0d778ab
--- /dev/null
+++ b/src/objecttypes/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
\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/objecttypes/accounts/tests/keycloak_cassets/happy_flow.yaml b/src/objecttypes/accounts/tests/keycloak_cassets/happy_flow.yaml
new file mode 100644
index 00000000..388adf3d
--- /dev/null
+++ b/src/objecttypes/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
\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/objecttypes/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml b/src/objecttypes/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml
new file mode 100644
index 00000000..fd490802
--- /dev/null
+++ b/src/objecttypes/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
\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/objecttypes/accounts/tests/test_oidc.py b/src/objecttypes/accounts/tests/test_oidc.py
index b677f192..4a9c5c92 100644
--- a/src/objecttypes/accounts/tests/test_oidc.py
+++ b/src/objecttypes/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 objecttypes.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/objecttypes/urls.py b/src/objecttypes/urls.py
index 13df6ad1..342de18e 100644
--- a/src/objecttypes/urls.py
+++ b/src/objecttypes/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 = "objecttypes.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/objecttypes/utils/tests/__init__.py b/src/objecttypes/utils/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/objecttypes/utils/tests/keycloak.py b/src/objecttypes/utils/tests/keycloak.py
new file mode 100644
index 00000000..73633ed6
--- /dev/null
+++ b/src/objecttypes/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