wip: Add KC-client and basic methods, signal handler
This commit is contained in:
parent
a14a09f1ca
commit
aa3f222112
|
|
@ -631,6 +631,12 @@ OAUTH_SIGNIN_REDIRECT_URI = env(
|
|||
"OAUTH_SIGNIN_REDIRECT_URI", default="http://localhost:8000/sso/callback"
|
||||
)
|
||||
|
||||
OAUTH_SIGNIN_URL = env("OAUTH_SIGNIN_URL", default="")
|
||||
OAUTH_SIGNIN_REALM = env("OAUTH_SIGNIN_REALM", default="vbv")
|
||||
OAUTH_SIGNIN_ADMIN_CLIENT_ID = env("OAUTH_SIGNIN_ADMIN_CLIENT_ID", default="")
|
||||
OAUTH_SIGNIN_ADMIN_CLIENT_SECRET = env("OAUTH_SIGNIN_ADMIN_CLIENT_SECRET", default="")
|
||||
OAUTH_SYNC_ROLES = env.bool("OAUTH_SYNC_ROLES", default=False)
|
||||
|
||||
GRAPHENE = {
|
||||
"SCHEMA": "vbv_lernwelt.core.schema.schema",
|
||||
"SCHEMA_OUTPUT": "../client/src/gql/schema.graphql",
|
||||
|
|
|
|||
|
|
@ -2,79 +2,84 @@
|
|||
# This file is autogenerated by pip-compile with Python 3.10
|
||||
# by the following command:
|
||||
#
|
||||
# pip-compile --output-file=requirements-dev.txt requirements-dev.in
|
||||
# pip-compile requirements-dev.in
|
||||
#
|
||||
aniso8601==9.0.1
|
||||
# via graphene
|
||||
anyascii==0.3.2
|
||||
# via wagtail
|
||||
anyio==3.7.1
|
||||
# via watchfiles
|
||||
appnope==0.1.3
|
||||
# via ipython
|
||||
argon2-cffi==21.3.0
|
||||
anyio==4.4.0
|
||||
# via
|
||||
# httpx
|
||||
# watchfiles
|
||||
argon2-cffi==23.1.0
|
||||
# via -r requirements.in
|
||||
argon2-cffi-bindings==21.2.0
|
||||
# via argon2-cffi
|
||||
asgiref==3.7.2
|
||||
# via django
|
||||
astroid==2.15.6
|
||||
asgiref==3.8.1
|
||||
# via
|
||||
# django
|
||||
# django-cors-headers
|
||||
# django-stubs
|
||||
astroid==3.2.2
|
||||
# via pylint
|
||||
asttokens==2.2.1
|
||||
asttokens==2.4.1
|
||||
# via stack-data
|
||||
async-timeout==4.0.2
|
||||
async-property==0.2.2
|
||||
# via python-keycloak
|
||||
async-timeout==4.0.3
|
||||
# via redis
|
||||
attrs==23.1.0
|
||||
attrs==23.2.0
|
||||
# via
|
||||
# jsonschema
|
||||
# referencing
|
||||
# usort
|
||||
authlib==1.2.1
|
||||
authlib==1.3.1
|
||||
# via -r requirements.in
|
||||
azure-core==1.29.1
|
||||
azure-core==1.30.2
|
||||
# via
|
||||
# azure-identity
|
||||
# azure-storage-blob
|
||||
azure-identity==1.14.0
|
||||
azure-identity==1.17.0
|
||||
# via -r requirements.in
|
||||
azure-storage-blob==12.17.0
|
||||
azure-storage-blob==12.20.0
|
||||
# via -r requirements.in
|
||||
backcall==0.2.0
|
||||
# via ipython
|
||||
bcrypt==4.0.1
|
||||
bcrypt==4.1.3
|
||||
# via paramiko
|
||||
beautifulsoup4==4.11.2
|
||||
# via wagtail
|
||||
black==23.7.0
|
||||
black==24.4.2
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# ufmt
|
||||
boto3==1.28.23
|
||||
boto3==1.34.129
|
||||
# via -r requirements.in
|
||||
botocore==1.31.23
|
||||
botocore==1.34.129
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
brotli==1.0.9
|
||||
brotli==1.1.0
|
||||
# via whitenoise
|
||||
build==0.10.0
|
||||
build==1.2.1
|
||||
# via pip-tools
|
||||
caprover-api @ git+https://github.com/iterativ/Caprover-API.git@5013f8fc929e8e3281b9d609e968a782e8e99530
|
||||
# via -r requirements-dev.in
|
||||
certifi==2023.7.22
|
||||
certifi==2024.6.2
|
||||
# via
|
||||
# httpcore
|
||||
# httpx
|
||||
# requests
|
||||
# sentry-sdk
|
||||
cffi==1.15.1
|
||||
cffi==1.16.0
|
||||
# via
|
||||
# argon2-cffi-bindings
|
||||
# cryptography
|
||||
# pynacl
|
||||
cfgv==3.3.1
|
||||
cfgv==3.4.0
|
||||
# via pre-commit
|
||||
charset-normalizer==3.2.0
|
||||
charset-normalizer==3.3.2
|
||||
# via requests
|
||||
click==8.1.6
|
||||
click==8.1.7
|
||||
# via
|
||||
# -r requirements.in
|
||||
# black
|
||||
|
|
@ -84,17 +89,18 @@ click==8.1.6
|
|||
# ufmt
|
||||
# usort
|
||||
# uvicorn
|
||||
concurrent-log-handler==0.9.24
|
||||
concurrent-log-handler==0.9.25
|
||||
# via -r requirements.in
|
||||
coverage==7.2.7
|
||||
coverage==7.5.3
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# django-coverage-plugin
|
||||
cryptography==41.0.3
|
||||
cryptography==42.0.8
|
||||
# via
|
||||
# authlib
|
||||
# azure-identity
|
||||
# azure-storage-blob
|
||||
# jwcrypto
|
||||
# msal
|
||||
# paramiko
|
||||
# pyjwt
|
||||
|
|
@ -104,13 +110,15 @@ decorator==5.1.1
|
|||
# ipython
|
||||
defusedxml==0.7.1
|
||||
# via willow
|
||||
dill==0.3.7
|
||||
deprecation==2.1.0
|
||||
# via python-keycloak
|
||||
dill==0.3.8
|
||||
# via pylint
|
||||
distlib==0.3.7
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
dj-database-url==2.0.0
|
||||
dj-database-url==2.2.0
|
||||
# via -r requirements.in
|
||||
django==3.2.20
|
||||
django==3.2.25
|
||||
# via
|
||||
# -r requirements.in
|
||||
# dj-database-url
|
||||
|
|
@ -137,96 +145,99 @@ django==3.2.20
|
|||
# jsonfield
|
||||
# wagtail
|
||||
# wagtail-localize
|
||||
django-click==2.3.0
|
||||
django-click==2.4.0
|
||||
# via -r requirements.in
|
||||
django-constance==3.1.0
|
||||
# via -r requirements.in
|
||||
django-cors-headers==4.2.0
|
||||
django-cors-headers==4.3.1
|
||||
# via -r requirements.in
|
||||
django-coverage-plugin==3.1.0
|
||||
# via -r requirements-dev.in
|
||||
django-csp==3.7
|
||||
django-csp==3.8
|
||||
# via -r requirements.in
|
||||
django-debug-toolbar==4.1.0
|
||||
django-debug-toolbar==4.3.0
|
||||
# via -r requirements-dev.in
|
||||
django-extensions==3.2.3
|
||||
# via -r requirements-dev.in
|
||||
django-filter==23.2
|
||||
django-filter==23.5
|
||||
# via wagtail
|
||||
django-ipware==5.0.0
|
||||
django-ipware==7.0.1
|
||||
# via -r requirements.in
|
||||
django-jsonform==2.18.0
|
||||
django-jsonform==2.22.0
|
||||
# via -r requirements.in
|
||||
django-model-utils==4.3.1
|
||||
django-model-utils==4.5.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django-notifications-hq
|
||||
django-modelcluster==6.0
|
||||
django-modelcluster==6.3
|
||||
# via wagtail
|
||||
django-notifications-hq==1.8.2
|
||||
django-notifications-hq==1.8.3
|
||||
# via -r requirements.in
|
||||
django-permissionedforms==0.1
|
||||
# via wagtail
|
||||
django-picklefield==3.1
|
||||
django-picklefield==3.2
|
||||
# via django-constance
|
||||
django-ratelimit==4.1.0
|
||||
# via -r requirements.in
|
||||
django-redis==5.3.0
|
||||
django-redis==5.4.0
|
||||
# via -r requirements.in
|
||||
django-storages==1.13.2
|
||||
django-storages==1.14.3
|
||||
# via -r requirements.in
|
||||
django-stubs==4.2.3
|
||||
django-stubs==5.0.2
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# djangorestframework-stubs
|
||||
django-stubs-ext==4.2.2
|
||||
django-stubs-ext==5.0.2
|
||||
# via django-stubs
|
||||
django-taggit==4.0.0
|
||||
# via wagtail
|
||||
django-treebeard==4.7
|
||||
django-treebeard==4.7.1
|
||||
# via wagtail
|
||||
djangorestframework==3.14.0
|
||||
django-watchfiles @ https://github.com/q0w/django-watchfiles/archive/issue-1.zip
|
||||
# via -r requirements-dev.in
|
||||
djangorestframework==3.15.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# drf-spectacular
|
||||
# wagtail
|
||||
djangorestframework-stubs==3.14.2
|
||||
djangorestframework-stubs==3.15.0
|
||||
# via -r requirements-dev.in
|
||||
draftjs-exporter==2.1.7
|
||||
# via wagtail
|
||||
drf-spectacular==0.26.4
|
||||
drf-spectacular==0.27.2
|
||||
# via -r requirements.in
|
||||
environs==9.5.0
|
||||
environs==11.0.0
|
||||
# via -r requirements.in
|
||||
et-xmlfile==1.1.0
|
||||
# via openpyxl
|
||||
exceptiongroup==1.1.2
|
||||
exceptiongroup==1.2.1
|
||||
# via
|
||||
# anyio
|
||||
# ipython
|
||||
# pytest
|
||||
execnet==2.0.2
|
||||
execnet==2.1.1
|
||||
# via pytest-xdist
|
||||
executing==1.2.0
|
||||
executing==2.0.1
|
||||
# via stack-data
|
||||
factory-boy==3.3.0
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# wagtail-factories
|
||||
faker==19.3.0
|
||||
faker==25.8.0
|
||||
# via factory-boy
|
||||
filelock==3.12.2
|
||||
filelock==3.15.1
|
||||
# via virtualenv
|
||||
filetype==1.2.0
|
||||
# via willow
|
||||
flake8==6.1.0
|
||||
flake8==7.1.0
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# flake8-isort
|
||||
flake8-isort==6.0.0
|
||||
flake8-isort==6.1.1
|
||||
# via -r requirements-dev.in
|
||||
freezegun==1.2.2
|
||||
freezegun==1.5.1
|
||||
# via -r requirements-dev.in
|
||||
gitdb==4.0.10
|
||||
gitdb==4.0.11
|
||||
# via gitdb2
|
||||
gitdb2==4.0.2
|
||||
# via gitpython
|
||||
|
|
@ -234,7 +245,7 @@ gitpython==3.0.6
|
|||
# via trufflehog
|
||||
graphene==3.3
|
||||
# via graphene-django
|
||||
graphene-django==3.1.5
|
||||
graphene-django==3.2.2
|
||||
# via wagtail-grapple
|
||||
graphql-core==3.2.3
|
||||
# via
|
||||
|
|
@ -245,19 +256,26 @@ graphql-relay==3.2.0
|
|||
# via
|
||||
# graphene
|
||||
# graphene-django
|
||||
gunicorn==21.2.0
|
||||
gunicorn==22.0.0
|
||||
# via -r requirements.in
|
||||
h11==0.14.0
|
||||
# via uvicorn
|
||||
# via
|
||||
# httpcore
|
||||
# uvicorn
|
||||
html5lib==1.1
|
||||
# via wagtail
|
||||
httptools==0.6.0
|
||||
httpcore==1.0.5
|
||||
# via httpx
|
||||
httptools==0.6.1
|
||||
# via uvicorn
|
||||
identify==2.5.26
|
||||
httpx==0.27.0
|
||||
# via python-keycloak
|
||||
identify==2.5.36
|
||||
# via pre-commit
|
||||
idna==3.4
|
||||
idna==3.7
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
# requests
|
||||
inflection==0.5.1
|
||||
# via drf-spectacular
|
||||
|
|
@ -265,15 +283,15 @@ iniconfig==2.0.0
|
|||
# via pytest
|
||||
ipdb==0.13.13
|
||||
# via -r requirements-dev.in
|
||||
ipython==8.14.0
|
||||
ipython==8.25.0
|
||||
# via ipdb
|
||||
isodate==0.6.1
|
||||
# via azure-storage-blob
|
||||
isort==5.12.0
|
||||
isort==5.13.2
|
||||
# via
|
||||
# flake8-isort
|
||||
# pylint
|
||||
jedi==0.19.0
|
||||
jedi==0.19.1
|
||||
# via ipython
|
||||
jmespath==1.0.1
|
||||
# via
|
||||
|
|
@ -281,21 +299,21 @@ jmespath==1.0.1
|
|||
# botocore
|
||||
jsonfield==3.1.0
|
||||
# via django-notifications-hq
|
||||
jsonschema==4.19.0
|
||||
jsonschema==4.22.0
|
||||
# via drf-spectacular
|
||||
jsonschema-specifications==2023.7.1
|
||||
jsonschema-specifications==2023.12.1
|
||||
# via jsonschema
|
||||
jwcrypto==1.5.6
|
||||
# via python-keycloak
|
||||
l18n==2021.3
|
||||
# via wagtail
|
||||
lazy-object-proxy==1.9.0
|
||||
# via astroid
|
||||
libcst==1.0.1
|
||||
libcst==1.4.0
|
||||
# via
|
||||
# ufmt
|
||||
# usort
|
||||
marshmallow==3.20.1
|
||||
marshmallow==3.21.3
|
||||
# via environs
|
||||
matplotlib-inline==0.1.6
|
||||
matplotlib-inline==0.1.7
|
||||
# via ipython
|
||||
mccabe==0.7.0
|
||||
# via
|
||||
|
|
@ -305,148 +323,166 @@ moreorless==0.4.0
|
|||
# via
|
||||
# ufmt
|
||||
# usort
|
||||
msal==1.23.0
|
||||
msal==1.28.1
|
||||
# via
|
||||
# azure-identity
|
||||
# msal-extensions
|
||||
msal-extensions==1.0.0
|
||||
msal-extensions==1.1.0
|
||||
# via azure-identity
|
||||
mypy==1.4.1
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# django-stubs
|
||||
# djangorestframework-stubs
|
||||
mypy==1.10.0
|
||||
# via -r requirements-dev.in
|
||||
mypy-extensions==1.0.0
|
||||
# via
|
||||
# black
|
||||
# mypy
|
||||
# typing-inspect
|
||||
newrelic==8.11.0
|
||||
newrelic==9.11.0
|
||||
# via -r requirements.in
|
||||
nodeenv==1.8.0
|
||||
nodeenv==1.9.1
|
||||
# via pre-commit
|
||||
openpyxl==3.1.2
|
||||
openpyxl==3.1.4
|
||||
# via
|
||||
# -r requirements.in
|
||||
# wagtail
|
||||
packaging==23.1
|
||||
packaging==24.1
|
||||
# via
|
||||
# black
|
||||
# build
|
||||
# deprecation
|
||||
# gunicorn
|
||||
# marshmallow
|
||||
# msal-extensions
|
||||
# pytest
|
||||
# pytest-sugar
|
||||
<<<<<<< HEAD
|
||||
paramiko==3.3.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# sftpserver
|
||||
parso==0.8.3
|
||||
=======
|
||||
paramiko==3.4.0
|
||||
# via -r requirements.in
|
||||
parso==0.8.4
|
||||
>>>>>>> 9e6b9a1e (wip: Add KC-client and basic methods, signal handler)
|
||||
# via jedi
|
||||
pathspec==0.11.2
|
||||
pathspec==0.12.1
|
||||
# via
|
||||
# black
|
||||
# trailrunner
|
||||
pexpect==4.8.0
|
||||
pexpect==4.9.0
|
||||
# via ipython
|
||||
pickleshare==0.7.5
|
||||
# via ipython
|
||||
pillow==10.0.0
|
||||
pillow==10.3.0
|
||||
# via
|
||||
# -r requirements.in
|
||||
# pillow-heif
|
||||
# wagtail
|
||||
pillow-heif==0.13.0
|
||||
pillow-heif==0.16.0
|
||||
# via willow
|
||||
pip-tools==7.3.0
|
||||
pip-tools==7.4.1
|
||||
# via -r requirements-dev.in
|
||||
platformdirs==3.10.0
|
||||
platformdirs==4.2.2
|
||||
# via
|
||||
# black
|
||||
# pylint
|
||||
# virtualenv
|
||||
pluggy==1.2.0
|
||||
pluggy==1.5.0
|
||||
# via pytest
|
||||
polib==1.2.0
|
||||
# via wagtail-localize
|
||||
portalocker==2.7.0
|
||||
portalocker==2.8.2
|
||||
# via
|
||||
# concurrent-log-handler
|
||||
# msal-extensions
|
||||
pre-commit==3.3.3
|
||||
pre-commit==3.7.1
|
||||
# via -r requirements-dev.in
|
||||
promise==2.3
|
||||
# via graphene-django
|
||||
prompt-toolkit==3.0.39
|
||||
prompt-toolkit==3.0.47
|
||||
# via ipython
|
||||
psycopg2-binary==2.9.7
|
||||
psycopg2-binary==2.9.9
|
||||
# via -r requirements.in
|
||||
ptyprocess==0.7.0
|
||||
# via pexpect
|
||||
pure-eval==0.2.2
|
||||
# via stack-data
|
||||
pycodestyle==2.11.0
|
||||
pycodestyle==2.12.0
|
||||
# via flake8
|
||||
pycparser==2.21
|
||||
pycparser==2.22
|
||||
# via cffi
|
||||
pycryptodome==3.18.0
|
||||
pycryptodome==3.20.0
|
||||
# via -r requirements.in
|
||||
pyflakes==3.1.0
|
||||
pyflakes==3.2.0
|
||||
# via flake8
|
||||
pygments==2.16.1
|
||||
pygments==2.18.0
|
||||
# via ipython
|
||||
pyjwt[crypto]==2.8.0
|
||||
<<<<<<< HEAD
|
||||
# via msal
|
||||
pylint==2.17.5
|
||||
=======
|
||||
# via
|
||||
# msal
|
||||
# pyjwt
|
||||
pylint==3.2.3
|
||||
>>>>>>> 9e6b9a1e (wip: Add KC-client and basic methods, signal handler)
|
||||
# via
|
||||
# pylint-django
|
||||
# pylint-plugin-utils
|
||||
pylint-django==2.5.3
|
||||
pylint-django==2.5.5
|
||||
# via -r requirements-dev.in
|
||||
pylint-plugin-utils==0.8.2
|
||||
# via pylint-django
|
||||
pynacl==1.5.0
|
||||
# via paramiko
|
||||
pyproject-hooks==1.0.0
|
||||
# via build
|
||||
pytest==7.4.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via
|
||||
# build
|
||||
# pip-tools
|
||||
pytest==8.2.2
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# pytest-django
|
||||
# pytest-order
|
||||
# pytest-sugar
|
||||
# pytest-xdist
|
||||
pytest-django==4.5.2
|
||||
pytest-django==4.8.0
|
||||
# via -r requirements-dev.in
|
||||
<<<<<<< HEAD
|
||||
pytest-order==1.2.1
|
||||
# via -r requirements-dev.in
|
||||
pytest-sugar==0.9.7
|
||||
=======
|
||||
pytest-sugar==1.0.0
|
||||
>>>>>>> 9e6b9a1e (wip: Add KC-client and basic methods, signal handler)
|
||||
# via -r requirements-dev.in
|
||||
pytest-xdist==3.5.0
|
||||
pytest-xdist==3.6.1
|
||||
# via -r requirements-dev.in
|
||||
python-dateutil==2.8.2
|
||||
python-dateutil==2.9.0.post0
|
||||
# via
|
||||
# -r requirements.in
|
||||
# botocore
|
||||
# faker
|
||||
# freezegun
|
||||
python-dotenv==1.0.0
|
||||
python-dotenv==1.0.1
|
||||
# via
|
||||
# environs
|
||||
# uvicorn
|
||||
python-http-client==3.3.7
|
||||
# via sendgrid
|
||||
python-ipware==3.0.0
|
||||
# via django-ipware
|
||||
python-json-logger==2.0.7
|
||||
# via -r requirements.in
|
||||
python-slugify==8.0.1
|
||||
python-keycloak==4.1.0
|
||||
# via -r requirements.in
|
||||
pytz==2023.3
|
||||
python-slugify==8.0.4
|
||||
# via -r requirements.in
|
||||
pytz==2024.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django
|
||||
# django-modelcluster
|
||||
# django-notifications-hq
|
||||
# djangorestframework
|
||||
# l18n
|
||||
pyyaml==6.0.1
|
||||
# via
|
||||
|
|
@ -455,30 +491,34 @@ pyyaml==6.0.1
|
|||
# libcst
|
||||
# pre-commit
|
||||
# uvicorn
|
||||
redis==4.6.0
|
||||
redis==5.0.6
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django-redis
|
||||
referencing==0.30.2
|
||||
referencing==0.35.1
|
||||
# via
|
||||
# jsonschema
|
||||
# jsonschema-specifications
|
||||
requests==2.31.0
|
||||
requests==2.32.3
|
||||
# via
|
||||
# azure-core
|
||||
# caprover-api
|
||||
# djangorestframework-stubs
|
||||
# msal
|
||||
# python-keycloak
|
||||
# requests-toolbelt
|
||||
# wagtail
|
||||
rpds-py==0.9.2
|
||||
requests-toolbelt==1.0.0
|
||||
# via python-keycloak
|
||||
rpds-py==0.18.1
|
||||
# via
|
||||
# jsonschema
|
||||
# referencing
|
||||
s3transfer==0.6.1
|
||||
s3transfer==0.10.1
|
||||
# via boto3
|
||||
sendgrid==6.10.0
|
||||
sendgrid==6.11.0
|
||||
# via -r requirements.in
|
||||
sentry-sdk==1.29.2
|
||||
sentry-sdk==2.5.1
|
||||
# via -r requirements.in
|
||||
sftpserver @ git+https://github.com/lonetwin/sftpserver.git@1d16896d3f0f90d63d1caaf4e199f2a9dde6456f
|
||||
# via -r requirements-dev.in
|
||||
|
|
@ -491,29 +531,31 @@ six==1.16.0
|
|||
# l18n
|
||||
# promise
|
||||
# python-dateutil
|
||||
smmap==5.0.0
|
||||
smmap==5.0.1
|
||||
# via gitdb
|
||||
sniffio==1.3.0
|
||||
# via anyio
|
||||
soupsieve==2.4.1
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
soupsieve==2.5
|
||||
# via beautifulsoup4
|
||||
sqlparse==0.4.4
|
||||
sqlparse==0.5.0
|
||||
# via
|
||||
# django
|
||||
# django-debug-toolbar
|
||||
stack-data==0.6.2
|
||||
stack-data==0.6.3
|
||||
# via ipython
|
||||
starkbank-ecdsa==2.2.0
|
||||
# via sendgrid
|
||||
stdlibs==2022.10.9
|
||||
stdlibs==2024.5.15
|
||||
# via usort
|
||||
structlog==23.1.0
|
||||
structlog==24.2.0
|
||||
# via -r requirements.in
|
||||
swapper==1.3.0
|
||||
# via django-notifications-hq
|
||||
telepath==0.3.1
|
||||
# via wagtail
|
||||
termcolor==2.3.0
|
||||
termcolor==2.4.0
|
||||
# via pytest-sugar
|
||||
text-unidecode==1.3
|
||||
# via
|
||||
|
|
@ -530,9 +572,8 @@ tomli==2.0.1
|
|||
# mypy
|
||||
# pip-tools
|
||||
# pylint
|
||||
# pyproject-hooks
|
||||
# pytest
|
||||
tomlkit==0.12.1
|
||||
tomlkit==0.12.5
|
||||
# via
|
||||
# pylint
|
||||
# ufmt
|
||||
|
|
@ -540,7 +581,7 @@ trailrunner==1.4.0
|
|||
# via
|
||||
# ufmt
|
||||
# usort
|
||||
traitlets==5.9.0
|
||||
traitlets==5.14.3
|
||||
# via
|
||||
# ipython
|
||||
# matplotlib-inline
|
||||
|
|
@ -548,82 +589,95 @@ trufflehog==2.2.1
|
|||
# via -r requirements-dev.in
|
||||
trufflehogregexes==0.0.7
|
||||
# via trufflehog
|
||||
types-pytz==2023.3.0.0
|
||||
# via django-stubs
|
||||
types-pyyaml==6.0.12.11
|
||||
types-pyyaml==6.0.12.20240311
|
||||
# via
|
||||
# django-stubs
|
||||
# djangorestframework-stubs
|
||||
types-requests==2.31.0.2
|
||||
types-requests==2.32.0.20240602
|
||||
# via djangorestframework-stubs
|
||||
types-urllib3==1.26.25.14
|
||||
# via types-requests
|
||||
typing-extensions==4.7.1
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# anyio
|
||||
# asgiref
|
||||
# astroid
|
||||
# azure-core
|
||||
# azure-identity
|
||||
# azure-storage-blob
|
||||
# black
|
||||
# dj-database-url
|
||||
# django-stubs
|
||||
# django-stubs-ext
|
||||
# djangorestframework-stubs
|
||||
# libcst
|
||||
# ipython
|
||||
# jwcrypto
|
||||
# mypy
|
||||
# typing-inspect
|
||||
# ufmt
|
||||
# uvicorn
|
||||
# wagtail-localize
|
||||
typing-inspect==0.9.0
|
||||
# via libcst
|
||||
ufmt==2.2.0
|
||||
ufmt==2.7.0
|
||||
# via -r requirements-dev.in
|
||||
uritemplate==4.1.1
|
||||
# via drf-spectacular
|
||||
urllib3==1.26.16
|
||||
urllib3==2.2.2
|
||||
# via
|
||||
# botocore
|
||||
# requests
|
||||
# sentry-sdk
|
||||
usort==1.0.7
|
||||
# types-requests
|
||||
usort==1.0.8.post1
|
||||
# via ufmt
|
||||
uvicorn[standard]==0.23.2
|
||||
uvicorn[standard]==0.30.1
|
||||
# via -r requirements.in
|
||||
uvloop==0.17.0
|
||||
uvloop==0.19.0
|
||||
# via uvicorn
|
||||
virtualenv==20.24.2
|
||||
virtualenv==20.26.2
|
||||
# via pre-commit
|
||||
wagtail==5.1
|
||||
wagtail==5.2.5
|
||||
# via
|
||||
# -r requirements.in
|
||||
# wagtail-factories
|
||||
# wagtail-grapple
|
||||
# wagtail-headless-preview
|
||||
# wagtail-localize
|
||||
wagtail-factories==4.1.0
|
||||
wagtail-factories==4.2.1
|
||||
# via -r requirements.in
|
||||
wagtail-grapple==0.20.0
|
||||
wagtail-grapple==0.25.1
|
||||
# via -r requirements.in
|
||||
wagtail-headless-preview==0.6.0
|
||||
wagtail-headless-preview==0.8.0
|
||||
# via wagtail-grapple
|
||||
wagtail-localize==1.5.1
|
||||
wagtail-localize==1.9
|
||||
# via -r requirements.in
|
||||
<<<<<<< HEAD
|
||||
watchfiles==0.19.0
|
||||
# via uvicorn
|
||||
wcwidth==0.2.6
|
||||
=======
|
||||
watchfiles==0.22.0
|
||||
# via
|
||||
# django-watchfiles
|
||||
# uvicorn
|
||||
wcwidth==0.2.13
|
||||
>>>>>>> 9e6b9a1e (wip: Add KC-client and basic methods, signal handler)
|
||||
# via prompt-toolkit
|
||||
webencodings==0.5.1
|
||||
# via html5lib
|
||||
websockets==11.0.3
|
||||
websockets==12.0
|
||||
# via uvicorn
|
||||
wheel==0.41.1
|
||||
wheel==0.43.0
|
||||
# via pip-tools
|
||||
whitenoise[brotli]==6.5.0
|
||||
whitenoise[brotli]==6.6.0
|
||||
# via -r requirements.in
|
||||
<<<<<<< HEAD
|
||||
willow[heif]==1.6.1
|
||||
# via wagtail
|
||||
wrapt==1.15.0
|
||||
# via astroid
|
||||
=======
|
||||
willow[heif]==1.6.3
|
||||
# via
|
||||
# wagtail
|
||||
# willow
|
||||
>>>>>>> 9e6b9a1e (wip: Add KC-client and basic methods, signal handler)
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
# pip
|
||||
|
|
|
|||
|
|
@ -52,3 +52,5 @@ azure-identity
|
|||
boto3
|
||||
openpyxl
|
||||
newrelic
|
||||
python-keycloak
|
||||
|
||||
|
|
|
|||
|
|
@ -2,79 +2,90 @@
|
|||
# This file is autogenerated by pip-compile with Python 3.10
|
||||
# by the following command:
|
||||
#
|
||||
# pip-compile --output-file=requirements.txt requirements.in
|
||||
# pip-compile requirements.in
|
||||
#
|
||||
aniso8601==9.0.1
|
||||
# via graphene
|
||||
anyascii==0.3.2
|
||||
# via wagtail
|
||||
anyio==3.7.1
|
||||
# via watchfiles
|
||||
argon2-cffi==21.3.0
|
||||
anyio==4.4.0
|
||||
# via
|
||||
# httpx
|
||||
# watchfiles
|
||||
argon2-cffi==23.1.0
|
||||
# via -r requirements.in
|
||||
argon2-cffi-bindings==21.2.0
|
||||
# via argon2-cffi
|
||||
asgiref==3.7.2
|
||||
# via django
|
||||
async-timeout==4.0.2
|
||||
asgiref==3.8.1
|
||||
# via
|
||||
# django
|
||||
# django-cors-headers
|
||||
async-property==0.2.2
|
||||
# via python-keycloak
|
||||
async-timeout==4.0.3
|
||||
# via redis
|
||||
attrs==23.1.0
|
||||
attrs==23.2.0
|
||||
# via
|
||||
# jsonschema
|
||||
# referencing
|
||||
authlib==1.2.1
|
||||
authlib==1.3.1
|
||||
# via -r requirements.in
|
||||
azure-core==1.29.1
|
||||
azure-core==1.30.2
|
||||
# via
|
||||
# azure-identity
|
||||
# azure-storage-blob
|
||||
azure-identity==1.14.0
|
||||
azure-identity==1.17.0
|
||||
# via -r requirements.in
|
||||
azure-storage-blob==12.17.0
|
||||
azure-storage-blob==12.20.0
|
||||
# via -r requirements.in
|
||||
bcrypt==4.0.1
|
||||
bcrypt==4.1.3
|
||||
# via paramiko
|
||||
beautifulsoup4==4.11.2
|
||||
# via wagtail
|
||||
boto3==1.28.23
|
||||
boto3==1.34.129
|
||||
# via -r requirements.in
|
||||
botocore==1.31.23
|
||||
botocore==1.34.129
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
brotli==1.0.9
|
||||
brotli==1.1.0
|
||||
# via whitenoise
|
||||
certifi==2023.7.22
|
||||
certifi==2024.6.2
|
||||
# via
|
||||
# httpcore
|
||||
# httpx
|
||||
# requests
|
||||
# sentry-sdk
|
||||
cffi==1.15.1
|
||||
cffi==1.16.0
|
||||
# via
|
||||
# argon2-cffi-bindings
|
||||
# cryptography
|
||||
# pynacl
|
||||
charset-normalizer==3.2.0
|
||||
charset-normalizer==3.3.2
|
||||
# via requests
|
||||
click==8.1.6
|
||||
click==8.1.7
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django-click
|
||||
# uvicorn
|
||||
concurrent-log-handler==0.9.24
|
||||
concurrent-log-handler==0.9.25
|
||||
# via -r requirements.in
|
||||
cryptography==41.0.3
|
||||
cryptography==42.0.8
|
||||
# via
|
||||
# authlib
|
||||
# azure-identity
|
||||
# azure-storage-blob
|
||||
# jwcrypto
|
||||
# msal
|
||||
# paramiko
|
||||
# pyjwt
|
||||
defusedxml==0.7.1
|
||||
# via willow
|
||||
dj-database-url==2.0.0
|
||||
deprecation==2.1.0
|
||||
# via python-keycloak
|
||||
dj-database-url==2.2.0
|
||||
# via -r requirements.in
|
||||
django==3.2.20
|
||||
django==3.2.25
|
||||
# via
|
||||
# -r requirements.in
|
||||
# dj-database-url
|
||||
|
|
@ -97,66 +108,66 @@ django==3.2.20
|
|||
# jsonfield
|
||||
# wagtail
|
||||
# wagtail-localize
|
||||
django-click==2.3.0
|
||||
django-click==2.4.0
|
||||
# via -r requirements.in
|
||||
django-constance==3.1.0
|
||||
# via -r requirements.in
|
||||
django-cors-headers==4.2.0
|
||||
django-cors-headers==4.3.1
|
||||
# via -r requirements.in
|
||||
django-csp==3.7
|
||||
django-csp==3.8
|
||||
# via -r requirements.in
|
||||
django-filter==23.2
|
||||
django-filter==23.5
|
||||
# via wagtail
|
||||
django-ipware==5.0.0
|
||||
django-ipware==7.0.1
|
||||
# via -r requirements.in
|
||||
django-jsonform==2.18.0
|
||||
django-jsonform==2.22.0
|
||||
# via -r requirements.in
|
||||
django-model-utils==4.3.1
|
||||
django-model-utils==4.5.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django-notifications-hq
|
||||
django-modelcluster==6.0
|
||||
django-modelcluster==6.3
|
||||
# via wagtail
|
||||
django-notifications-hq==1.8.2
|
||||
django-notifications-hq==1.8.3
|
||||
# via -r requirements.in
|
||||
django-permissionedforms==0.1
|
||||
# via wagtail
|
||||
django-picklefield==3.1
|
||||
django-picklefield==3.2
|
||||
# via django-constance
|
||||
django-ratelimit==4.1.0
|
||||
# via -r requirements.in
|
||||
django-redis==5.3.0
|
||||
django-redis==5.4.0
|
||||
# via -r requirements.in
|
||||
django-storages==1.13.2
|
||||
django-storages==1.14.3
|
||||
# via -r requirements.in
|
||||
django-taggit==4.0.0
|
||||
# via wagtail
|
||||
django-treebeard==4.7
|
||||
django-treebeard==4.7.1
|
||||
# via wagtail
|
||||
djangorestframework==3.14.0
|
||||
djangorestframework==3.15.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# drf-spectacular
|
||||
# wagtail
|
||||
draftjs-exporter==2.1.7
|
||||
# via wagtail
|
||||
drf-spectacular==0.26.4
|
||||
drf-spectacular==0.27.2
|
||||
# via -r requirements.in
|
||||
environs==9.5.0
|
||||
environs==11.0.0
|
||||
# via -r requirements.in
|
||||
et-xmlfile==1.1.0
|
||||
# via openpyxl
|
||||
exceptiongroup==1.1.2
|
||||
exceptiongroup==1.2.1
|
||||
# via anyio
|
||||
factory-boy==3.3.0
|
||||
# via wagtail-factories
|
||||
faker==19.3.0
|
||||
faker==25.8.0
|
||||
# via factory-boy
|
||||
filetype==1.2.0
|
||||
# via willow
|
||||
graphene==3.3
|
||||
# via graphene-django
|
||||
graphene-django==3.1.5
|
||||
graphene-django==3.2.2
|
||||
# via wagtail-grapple
|
||||
graphql-core==3.2.3
|
||||
# via
|
||||
|
|
@ -167,17 +178,24 @@ graphql-relay==3.2.0
|
|||
# via
|
||||
# graphene
|
||||
# graphene-django
|
||||
gunicorn==21.2.0
|
||||
gunicorn==22.0.0
|
||||
# via -r requirements.in
|
||||
h11==0.14.0
|
||||
# via uvicorn
|
||||
# via
|
||||
# httpcore
|
||||
# uvicorn
|
||||
html5lib==1.1
|
||||
# via wagtail
|
||||
httptools==0.6.0
|
||||
httpcore==1.0.5
|
||||
# via httpx
|
||||
httptools==0.6.1
|
||||
# via uvicorn
|
||||
idna==3.4
|
||||
httpx==0.27.0
|
||||
# via python-keycloak
|
||||
idna==3.7
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
# requests
|
||||
inflection==0.5.1
|
||||
# via drf-spectacular
|
||||
|
|
@ -189,106 +207,119 @@ jmespath==1.0.1
|
|||
# botocore
|
||||
jsonfield==3.1.0
|
||||
# via django-notifications-hq
|
||||
jsonschema==4.19.0
|
||||
jsonschema==4.22.0
|
||||
# via drf-spectacular
|
||||
jsonschema-specifications==2023.7.1
|
||||
jsonschema-specifications==2023.12.1
|
||||
# via jsonschema
|
||||
jwcrypto==1.5.6
|
||||
# via python-keycloak
|
||||
l18n==2021.3
|
||||
# via wagtail
|
||||
marshmallow==3.20.1
|
||||
marshmallow==3.21.3
|
||||
# via environs
|
||||
msal==1.23.0
|
||||
msal==1.28.1
|
||||
# via
|
||||
# azure-identity
|
||||
# msal-extensions
|
||||
msal-extensions==1.0.0
|
||||
msal-extensions==1.1.0
|
||||
# via azure-identity
|
||||
newrelic==8.11.0
|
||||
newrelic==9.11.0
|
||||
# via -r requirements.in
|
||||
openpyxl==3.1.2
|
||||
openpyxl==3.1.4
|
||||
# via
|
||||
# -r requirements.in
|
||||
# wagtail
|
||||
packaging==23.1
|
||||
packaging==24.1
|
||||
# via
|
||||
# deprecation
|
||||
# gunicorn
|
||||
# marshmallow
|
||||
paramiko==3.3.1
|
||||
# msal-extensions
|
||||
paramiko==3.4.0
|
||||
# via -r requirements.in
|
||||
pillow==10.0.0
|
||||
pillow==10.3.0
|
||||
# via
|
||||
# -r requirements.in
|
||||
# pillow-heif
|
||||
# wagtail
|
||||
pillow-heif==0.13.0
|
||||
pillow-heif==0.16.0
|
||||
# via willow
|
||||
polib==1.2.0
|
||||
# via wagtail-localize
|
||||
portalocker==2.7.0
|
||||
portalocker==2.8.2
|
||||
# via
|
||||
# concurrent-log-handler
|
||||
# msal-extensions
|
||||
promise==2.3
|
||||
# via graphene-django
|
||||
psycopg2-binary==2.9.7
|
||||
psycopg2-binary==2.9.9
|
||||
# via -r requirements.in
|
||||
pycparser==2.21
|
||||
pycparser==2.22
|
||||
# via cffi
|
||||
pycryptodome==3.18.0
|
||||
pycryptodome==3.20.0
|
||||
# via -r requirements.in
|
||||
pyjwt[crypto]==2.8.0
|
||||
# via msal
|
||||
# via
|
||||
# msal
|
||||
# pyjwt
|
||||
pynacl==1.5.0
|
||||
# via paramiko
|
||||
python-dateutil==2.8.2
|
||||
python-dateutil==2.9.0.post0
|
||||
# via
|
||||
# -r requirements.in
|
||||
# botocore
|
||||
# faker
|
||||
python-dotenv==1.0.0
|
||||
python-dotenv==1.0.1
|
||||
# via
|
||||
# environs
|
||||
# uvicorn
|
||||
python-http-client==3.3.7
|
||||
# via sendgrid
|
||||
python-ipware==3.0.0
|
||||
# via django-ipware
|
||||
python-json-logger==2.0.7
|
||||
# via -r requirements.in
|
||||
python-slugify==8.0.1
|
||||
python-keycloak==4.1.0
|
||||
# via -r requirements.in
|
||||
pytz==2023.3
|
||||
python-slugify==8.0.4
|
||||
# via -r requirements.in
|
||||
pytz==2024.1
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django
|
||||
# django-modelcluster
|
||||
# django-notifications-hq
|
||||
# djangorestframework
|
||||
# l18n
|
||||
pyyaml==6.0.1
|
||||
# via
|
||||
# drf-spectacular
|
||||
# uvicorn
|
||||
redis==4.6.0
|
||||
redis==5.0.6
|
||||
# via
|
||||
# -r requirements.in
|
||||
# django-redis
|
||||
referencing==0.30.2
|
||||
referencing==0.35.1
|
||||
# via
|
||||
# jsonschema
|
||||
# jsonschema-specifications
|
||||
requests==2.31.0
|
||||
requests==2.32.3
|
||||
# via
|
||||
# azure-core
|
||||
# msal
|
||||
# python-keycloak
|
||||
# requests-toolbelt
|
||||
# wagtail
|
||||
rpds-py==0.9.2
|
||||
requests-toolbelt==1.0.0
|
||||
# via python-keycloak
|
||||
rpds-py==0.18.1
|
||||
# via
|
||||
# jsonschema
|
||||
# referencing
|
||||
s3transfer==0.6.1
|
||||
s3transfer==0.10.1
|
||||
# via boto3
|
||||
sendgrid==6.10.0
|
||||
sendgrid==6.11.0
|
||||
# via -r requirements.in
|
||||
sentry-sdk==1.29.2
|
||||
sentry-sdk==2.5.1
|
||||
# via -r requirements.in
|
||||
six==1.16.0
|
||||
# via
|
||||
|
|
@ -298,15 +329,17 @@ six==1.16.0
|
|||
# l18n
|
||||
# promise
|
||||
# python-dateutil
|
||||
sniffio==1.3.0
|
||||
# via anyio
|
||||
soupsieve==2.4.1
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
soupsieve==2.5
|
||||
# via beautifulsoup4
|
||||
sqlparse==0.4.4
|
||||
sqlparse==0.5.0
|
||||
# via django
|
||||
starkbank-ecdsa==2.2.0
|
||||
# via sendgrid
|
||||
structlog==23.1.0
|
||||
structlog==24.2.0
|
||||
# via -r requirements.in
|
||||
swapper==1.3.0
|
||||
# via django-notifications-hq
|
||||
|
|
@ -316,47 +349,52 @@ text-unidecode==1.3
|
|||
# via
|
||||
# graphene-django
|
||||
# python-slugify
|
||||
typing-extensions==4.7.1
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# anyio
|
||||
# asgiref
|
||||
# azure-core
|
||||
# azure-identity
|
||||
# azure-storage-blob
|
||||
# dj-database-url
|
||||
# jwcrypto
|
||||
# uvicorn
|
||||
# wagtail-localize
|
||||
uritemplate==4.1.1
|
||||
# via drf-spectacular
|
||||
urllib3==1.26.16
|
||||
urllib3==2.2.2
|
||||
# via
|
||||
# botocore
|
||||
# requests
|
||||
# sentry-sdk
|
||||
uvicorn[standard]==0.23.2
|
||||
uvicorn[standard]==0.30.1
|
||||
# via -r requirements.in
|
||||
uvloop==0.17.0
|
||||
uvloop==0.19.0
|
||||
# via uvicorn
|
||||
wagtail==5.1
|
||||
wagtail==5.2.5
|
||||
# via
|
||||
# -r requirements.in
|
||||
# wagtail-factories
|
||||
# wagtail-grapple
|
||||
# wagtail-headless-preview
|
||||
# wagtail-localize
|
||||
wagtail-factories==4.1.0
|
||||
wagtail-factories==4.2.1
|
||||
# via -r requirements.in
|
||||
wagtail-grapple==0.20.0
|
||||
wagtail-grapple==0.25.1
|
||||
# via -r requirements.in
|
||||
wagtail-headless-preview==0.6.0
|
||||
wagtail-headless-preview==0.8.0
|
||||
# via wagtail-grapple
|
||||
wagtail-localize==1.5.1
|
||||
wagtail-localize==1.9
|
||||
# via -r requirements.in
|
||||
watchfiles==0.19.0
|
||||
watchfiles==0.22.0
|
||||
# via uvicorn
|
||||
webencodings==0.5.1
|
||||
# via html5lib
|
||||
websockets==11.0.3
|
||||
websockets==12.0
|
||||
# via uvicorn
|
||||
whitenoise[brotli]==6.5.0
|
||||
whitenoise[brotli]==6.6.0
|
||||
# via -r requirements.in
|
||||
willow[heif]==1.6.1
|
||||
# via wagtail
|
||||
willow[heif]==1.6.3
|
||||
# via
|
||||
# wagtail
|
||||
# willow
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ from vbv_lernwelt.core.model_utils import find_available_slug
|
|||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.course.serializer_helpers import get_course_serializer_class
|
||||
from vbv_lernwelt.files.models import UploadFile
|
||||
from vbv_lernwelt.sso.role_sync.client import (
|
||||
add_roles_to_user,
|
||||
remove_roles_from_user,
|
||||
update_roles_for_user,
|
||||
)
|
||||
|
||||
|
||||
class CircleContactType(Enum):
|
||||
|
|
@ -293,6 +298,26 @@ class CourseSessionUser(models.Model):
|
|||
def __str__(self):
|
||||
return f"{self.user} ({self.course_session.title})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.created_at is None:
|
||||
add_roles_to_user(
|
||||
self.user, [(self.course_session.course.slug, [self.role])]
|
||||
)
|
||||
else:
|
||||
old_csu = CourseSessionUser.objects.get(pk=self.pk)
|
||||
update_roles_for_user(
|
||||
self.user,
|
||||
add_course_roles=[(self.course_session.course.slug, [self.role])],
|
||||
remove_course_roles=[(self.course_session.course.slug, [old_csu.role])],
|
||||
)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def remove_sso_roles_from_user(cls, instance: "CourseSessionUser"):
|
||||
remove_roles_from_user(
|
||||
instance.user, [(instance.course_session.course.slug, [instance.role])]
|
||||
)
|
||||
|
||||
|
||||
class CircleDocument(models.Model):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
from django.db.models.signals import post_save
|
||||
from django.db.models.signals import post_delete, post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
from vbv_lernwelt.course.models import Course, CourseConfiguration
|
||||
from vbv_lernwelt.course.models import Course, CourseConfiguration, CourseSessionUser
|
||||
|
||||
|
||||
@receiver(post_save, sender=Course)
|
||||
def create_course_configuration(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
CourseConfiguration.objects.create(course=instance)
|
||||
|
||||
|
||||
@receiver(post_delete, sender=CourseSessionUser)
|
||||
def after_delete(sender, instance, **kwargs):
|
||||
CourseSessionUser.remove_sso_roles_from_user(instance)
|
||||
|
|
|
|||
|
|
@ -4,5 +4,4 @@ from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
|||
|
||||
|
||||
@admin.register(CourseSessionGroup)
|
||||
class CourseSessionAssignmentAdmin(admin.ModelAdmin):
|
||||
...
|
||||
class CourseSessionAssignmentAdmin(admin.ModelAdmin): ...
|
||||
|
|
|
|||
|
|
@ -153,9 +153,9 @@ def fetch_course_session_all_users(courses: List[int], excluded_domains=None):
|
|||
|
||||
def generate_export_response(cs_users: List[User]) -> HttpResponse:
|
||||
response = HttpResponse(content_type="text/csv; charset=utf-8")
|
||||
response[
|
||||
"Content-Disposition"
|
||||
] = f"attachment; filename=edoniq_user_export_{date.today().strftime('%Y%m%d')}.csv"
|
||||
response["Content-Disposition"] = (
|
||||
f"attachment; filename=edoniq_user_export_{date.today().strftime('%Y%m%d')}.csv"
|
||||
)
|
||||
|
||||
response.write("\ufeff".encode("utf8")) # UTF-8 BOM
|
||||
|
||||
|
|
|
|||
|
|
@ -125,9 +125,9 @@ def _handle_feedback_export_action(course_seesions, file_name):
|
|||
response = HttpResponse(
|
||||
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
)
|
||||
response[
|
||||
"Content-Disposition"
|
||||
] = f"attachment; filename={make_export_filename(file_name)}"
|
||||
response["Content-Disposition"] = (
|
||||
f"attachment; filename={make_export_filename(file_name)}"
|
||||
)
|
||||
response.write(excel_bytes)
|
||||
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -493,6 +493,7 @@ def create_or_update_user(
|
|||
sso_id: str = None,
|
||||
contract_number: str = "",
|
||||
date_of_birth: str = "",
|
||||
intermediate_sso_id: str = "", # from keycloak
|
||||
) -> User:
|
||||
logger.debug(
|
||||
"create_or_update_user",
|
||||
|
|
@ -537,6 +538,9 @@ def create_or_update_user(
|
|||
user.first_name = first_name or user.first_name
|
||||
user.last_name = last_name or user.last_name
|
||||
user.username = email
|
||||
user.additional_json_data = user.additional_json_data | {
|
||||
"intermediate_sso_id": intermediate_sso_id
|
||||
}
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ class TestNotificationService(TestCase):
|
|||
self.assertFalse(notification.emailed)
|
||||
|
||||
def test_send_notification_with_email(self):
|
||||
self.recipient.additional_json_data[
|
||||
"email_notification_categories"
|
||||
] = json.dumps(["USER_INTERACTION"])
|
||||
self.recipient.additional_json_data["email_notification_categories"] = (
|
||||
json.dumps(["USER_INTERACTION"])
|
||||
)
|
||||
self.recipient.save()
|
||||
|
||||
verb = "Anne hat deinen Auftrag bewertet"
|
||||
|
|
@ -146,9 +146,9 @@ class TestNotificationService(TestCase):
|
|||
self.assertFalse(notification.emailed)
|
||||
|
||||
# when the email was not sent, yet it will still send it afterwards...
|
||||
self.recipient.additional_json_data[
|
||||
"email_notification_categories"
|
||||
] = json.dumps(["USER_INTERACTION"])
|
||||
self.recipient.additional_json_data["email_notification_categories"] = (
|
||||
json.dumps(["USER_INTERACTION"])
|
||||
)
|
||||
self.recipient.save()
|
||||
|
||||
result = self.notification_service._send_notification(
|
||||
|
|
@ -188,9 +188,9 @@ class TestNotificationService(TestCase):
|
|||
self.assertFalse(self._has_sent_emails())
|
||||
|
||||
# Assert mail is sent if corresponding email notification type is enabled
|
||||
self.recipient.additional_json_data[
|
||||
"email_notification_categories"
|
||||
] = json.dumps(["USER_INTERACTION"])
|
||||
self.recipient.additional_json_data["email_notification_categories"] = (
|
||||
json.dumps(["USER_INTERACTION"])
|
||||
)
|
||||
self.recipient.save()
|
||||
self.notification_service._send_notification(
|
||||
sender=self.sender,
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ class SelfEvaluationFeedbackSerializer(serializers.ModelSerializer):
|
|||
return obj.learning_unit.get_circle().title
|
||||
|
||||
def get_criteria(self, obj):
|
||||
performance_criteria: List[
|
||||
PerformanceCriteria
|
||||
] = obj.learning_unit.performancecriteria_set.all()
|
||||
performance_criteria: List[PerformanceCriteria] = (
|
||||
obj.learning_unit.performancecriteria_set.all()
|
||||
)
|
||||
|
||||
criteria = []
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
import unicodedata
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
from django.conf import settings
|
||||
from keycloak import KeycloakAdmin, KeycloakOpenIDConnection
|
||||
|
||||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.sso.role_sync.roles import ROLE_IDS, SSO_ROLES
|
||||
|
||||
CourseRolesType = List[Tuple[str, List[str]]]
|
||||
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
keycloak_connection = KeycloakOpenIDConnection(
|
||||
server_url=settings.OAUTH_SIGNIN_URL,
|
||||
realm_name=settings.OAUTH_SIGNIN_REALM,
|
||||
user_realm_name=settings.OAUTH_SIGNIN_REALM,
|
||||
client_id=settings.OAUTH_SIGNIN_ADMIN_CLIENT_ID,
|
||||
client_secret_key=settings.OAUTH_SIGNIN_ADMIN_CLIENT_SECRET,
|
||||
verify=True,
|
||||
)
|
||||
|
||||
keycloak_admin = KeycloakAdmin(connection=keycloak_connection)
|
||||
|
||||
|
||||
# todo: handle errors
|
||||
|
||||
|
||||
def add_roles_to_user(user: User, course_roles: CourseRolesType):
|
||||
user_id = user.additional_json_data.get("intermediate_sso_id", "")
|
||||
if settings.OAUTH_SYNC_ROLES and user_id:
|
||||
request_roles = _get_role_request_data(course_roles)
|
||||
keycloak_admin.assign_realm_roles(
|
||||
user_id=user_id,
|
||||
roles=request_roles,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def remove_roles_from_user(user: User, course_roles: CourseRolesType):
|
||||
user_id = user.additional_json_data.get("intermediate_sso_id", "")
|
||||
if settings.OAUTH_SYNC_ROLES and user_id:
|
||||
request_roles = _get_role_request_data(course_roles)
|
||||
keycloak_admin.delete_realm_roles_of_user(
|
||||
user_id=user_id,
|
||||
roles=request_roles,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def update_roles_for_user(
|
||||
user: User, add_course_roles: CourseRolesType, remove_course_roles: CourseRolesType
|
||||
):
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
add_roles_to_user(user, add_course_roles)
|
||||
remove_roles_from_user(user, remove_course_roles)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_roles_for_user(user_id: str):
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
return keycloak_admin.get_realm_roles_of_user(
|
||||
user_id=user_id,
|
||||
)
|
||||
return []
|
||||
|
||||
|
||||
# create sso-ID user and set roles
|
||||
# sync
|
||||
|
||||
|
||||
def _get_role_request_data(course_roles: CourseRolesType) -> List[Dict[str, str]]:
|
||||
request_roles = []
|
||||
for item in course_roles:
|
||||
course_slug, roles = item
|
||||
sanitized_course_slug = _remove_accents(course_slug)
|
||||
oauth_roles = _create_role_names(sanitized_course_slug, roles)
|
||||
return request_roles + [
|
||||
{"id": ROLE_IDS[role], "name": role} for role in oauth_roles
|
||||
]
|
||||
return request_roles
|
||||
|
||||
|
||||
def _create_role_names(course_slug: str, roles: list) -> List[str]:
|
||||
return [SSO_ROLES[course_slug][role] for role in roles]
|
||||
|
||||
|
||||
def _remove_accents(input_str) -> str:
|
||||
nfkd_form = unicodedata.normalize("NFKD", input_str)
|
||||
return "".join([char for char in nfkd_form if not unicodedata.combining(char)])
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
SSO_ROLES = {
|
||||
"uberbetriebliche-kurse": {
|
||||
"MEMBER": "myvbv-uberbetriebliche-kurse-member",
|
||||
"EXPERT": "myvbv-uberbetriebliche-kurse-expert",
|
||||
"SUPERVISOR": "myvbv-uberbetriebliche-kurse-supervisor",
|
||||
"LEARNING_MENTOR": "myvbv-uberbetriebliche-kurse-mentor",
|
||||
},
|
||||
"cours-interentreprises": {
|
||||
"MEMBER": "myvbv-cours-interentreprises-member",
|
||||
"EXPERT": "myvbv-cours-interentreprises-expert",
|
||||
"SUPERVISOR": "myvbv-cours-interentreprises-supervisor",
|
||||
"LEARNING_MENTOR": "myvbv-cours-interentreprises-mentor",
|
||||
},
|
||||
"corso-interaziendale": {
|
||||
"MEMBER": "myvbv-corso-interaziendale-member",
|
||||
"EXPERT": "myvbv-corso-interaziendale-expert",
|
||||
"SUPERVISOR": "myvbv-corso-interaziendale-supervisor",
|
||||
"LEARNING_MENTOR": "myvbv-corso-interaziendale-mentor",
|
||||
},
|
||||
"versicherungsvermittler-in": {
|
||||
"MEMBER": "myvbv-versicherungsvermittler-in-member",
|
||||
"LEARNING_MENTOR": "myvbv-versicherungsvermittler-in-mentor",
|
||||
},
|
||||
"intermediaire-dassurance": {
|
||||
"MEMBER": "myvbv-intermediaire-dassurance-member",
|
||||
"LEARNING_MENTOR": "myvbv-intermediaire-dassurance-mentor",
|
||||
},
|
||||
"intermediarioa-assicurativoa": {
|
||||
"MEMBER": "myvbv-intermediarioa-assicurativoa-member",
|
||||
"LEARNING_MENTOR": "myvbv-intermediarioa-assicurativoa-mentor",
|
||||
},
|
||||
}
|
||||
|
||||
# https://sso.test.b.lernetz.host/auth/admin/vbv/console/#/vbv/roles
|
||||
ROLE_IDS = {
|
||||
"myvbv-uberbetriebliche-kurse-member": "0725f2d4-c3f3-48b7-83ec-06acfae630e6",
|
||||
"myvbv-uberbetriebliche-kurse-expert": "c7e33cb6-d227-4764-9b8e-d42af79fb46d",
|
||||
"myvbv-uberbetriebliche-kurse-supervisor": "d88a7486-7ff4-475c-b840-2e1e0a9decb8",
|
||||
"myvbv-uberbetriebliche-kurse-mentor": "db5f0e24-9512-4752-8c51-26b3aa6f7f6a",
|
||||
"myvbv-cours-interentreprises-member": "458c65f4-e969-4ba7-a546-77948641bc0b",
|
||||
"myvbv-cours-interentreprises-expert": "2ef51fc6-1e5a-427c-b4a9-314249ea24db",
|
||||
"myvbv-cours-interentreprises-supervisor": "23e5994e-c499-42e8-b956-bb098be793e1",
|
||||
"myvbv-cours-interentreprises-mentor": "cb37a093-32a3-479b-981e-0604b6b71f5e",
|
||||
"myvbv-corso-interaziendale-member": "4d9cfc61-b555-44b1-a52d-76231d12f0cd",
|
||||
"myvbv-corso-interaziendale-expert": "b2da77bd-c3c8-4d1e-9757-c016eaf219e3",
|
||||
"myvbv-corso-interaziendale-supervisor": "8e9ea3e4-e814-4704-906e-d39f595811eb",
|
||||
"myvbv-corso-interaziendale-mentor": "36fae39d-67f0-4ed6-9a1c-7d383be9e463",
|
||||
"myvbv-versicherungsvermittler-in-member": "3ab4eab2-7d7c-43bb-a927-4cf54f24ccc2",
|
||||
"myvbv-versicherungsvermittler-in-mentor": "12bf374a-293b-4abe-b255-7899eae31908",
|
||||
"myvbv-intermediaire-dassurance-member": "5400fdae-2c37-4738-8667-0bcb50ed3609",
|
||||
"myvbv-intermediaire-dassurance-mentor": "3bd737f9-731a-4548-aaf5-4c80175f2759",
|
||||
"myvbv-intermediarioa-assicurativoa-member": "9fbaaa0f-cf8c-45f2-93f6-7174cb18a982",
|
||||
"myvbv-intermediarioa-assicurativoa-mentor": "46b12e54-682e-44c0-b506-eab820138b66",
|
||||
}
|
||||
|
|
@ -116,6 +116,7 @@ def authorize_signin(request):
|
|||
sso_id=id_token.get("oid"),
|
||||
first_name=id_token.get("given_name", ""),
|
||||
last_name=id_token.get("family_name", ""),
|
||||
intermediate_sso_id=id_token.get("sub"),
|
||||
)
|
||||
|
||||
dj_login(request, user)
|
||||
|
|
|
|||
Loading…
Reference in New Issue