Merge branch 'master' into version-2021.12

This commit is contained in:
Jens Langhammer 2021-12-09 13:23:28 +01:00
commit ee0ddc3d17
67 changed files with 1225 additions and 677 deletions

View file

@ -89,9 +89,11 @@ jobs:
run: | run: |
# Copy current, latest config to local # Copy current, latest config to local
cp authentik/lib/default.yml local.env.yml cp authentik/lib/default.yml local.env.yml
cp -R .github ..
cp -R scripts ..
git checkout $(git describe --abbrev=0 --match 'version/*') git checkout $(git describe --abbrev=0 --match 'version/*')
git checkout $GITHUB_HEAD_REF -- .github rm -rf .github/ scripts/
git checkout $GITHUB_HEAD_REF -- scripts mv ../.github ../scripts .
- name: prepare - name: prepare
env: env:
INSTALL: ${{ steps.cache-pipenv.outputs.cache-hit }} INSTALL: ${{ steps.cache-pipenv.outputs.cache-hit }}
@ -105,6 +107,7 @@ jobs:
run: | run: |
set -x set -x
git fetch git fetch
git reset --hard HEAD
git checkout $GITHUB_HEAD_REF git checkout $GITHUB_HEAD_REF
pipenv sync --dev pipenv sync --dev
- name: prepare - name: prepare
@ -220,7 +223,7 @@ jobs:
testspace [e2e]unittest.xml --link=codecov testspace [e2e]unittest.xml --link=codecov
- if: ${{ always() }} - if: ${{ always() }}
uses: codecov/codecov-action@v2 uses: codecov/codecov-action@v2
build: ci-core-mark:
needs: needs:
- lint - lint
- test-migrations - test-migrations
@ -229,6 +232,11 @@ jobs:
- test-integration - test-integration
- test-e2e - test-e2e
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps:
- run: echo mark
build:
needs: ci-core-mark
runs-on: ubuntu-latest
timeout-minutes: 120 timeout-minutes: 120
strategy: strategy:
fail-fast: false fail-fast: false

View file

@ -30,10 +30,16 @@ jobs:
-w /app \ -w /app \
golangci/golangci-lint:v1.39.0 \ golangci/golangci-lint:v1.39.0 \
golangci-lint run -v --timeout 200s golangci-lint run -v --timeout 200s
ci-outpost-mark:
needs:
- lint-golint
runs-on: ubuntu-latest
steps:
- run: echo mark
build: build:
timeout-minutes: 120 timeout-minutes: 120
needs: needs:
- lint-golint - ci-outpost-mark
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View file

@ -65,12 +65,18 @@ jobs:
run: | run: |
cd web cd web
npm run lit-analyse npm run lit-analyse
build: ci-web-mark:
needs: needs:
- lint-eslint - lint-eslint
- lint-prettier - lint-prettier
- lint-lit-analyse - lint-lit-analyse
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps:
- run: echo mark
build:
needs:
- ci-web-mark
runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v2 - uses: actions/setup-node@v2

View file

@ -1,5 +1,5 @@
# Stage 1: Lock python dependencies # Stage 1: Lock python dependencies
FROM docker.io/python:3.9-slim-bullseye as locker FROM docker.io/python:3.10.1-slim-bullseye as locker
COPY ./Pipfile /app/ COPY ./Pipfile /app/
COPY ./Pipfile.lock /app/ COPY ./Pipfile.lock /app/
@ -28,7 +28,7 @@ ENV NODE_ENV=production
RUN cd /work/web && npm i && npm run build RUN cd /work/web && npm i && npm run build
# Stage 4: Build go proxy # Stage 4: Build go proxy
FROM docker.io/golang:1.17.3-bullseye AS builder FROM docker.io/golang:1.17.4-bullseye AS builder
WORKDIR /work WORKDIR /work
@ -44,7 +44,7 @@ COPY ./go.sum /work/go.sum
RUN go build -o /work/authentik ./cmd/server/main.go RUN go build -o /work/authentik ./cmd/server/main.go
# Stage 5: Run # Stage 5: Run
FROM docker.io/python:3.9-slim-bullseye FROM docker.io/python:3.10.1-slim-bullseye
WORKDIR / WORKDIR /
COPY --from=locker /app/requirements.txt / COPY --from=locker /app/requirements.txt /

View file

@ -84,6 +84,9 @@ migrate:
run: run:
go run -v cmd/server/main.go go run -v cmd/server/main.go
web-watch:
cd web && npm run watch
web: web-lint-fix web-lint web-extract web: web-lint-fix web-lint web-extract
web-lint-fix: web-lint-fix:

View file

@ -49,6 +49,7 @@ urllib3 = {extras = ["secure"],version = "*"}
uvicorn = {extras = ["standard"],version = "*"} uvicorn = {extras = ["standard"],version = "*"}
webauthn = "*" webauthn = "*"
xmlsec = "*" xmlsec = "*"
flower = "*"
[dev-packages] [dev-packages]
bandit = "*" bandit = "*"

549
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "cb44f399eed2d9be5057c2c1ce572435b6a449cdfdf13abfee8787db1f2856d9" "sha256": "6f7f70af39ff6e2d95dd62e225a52c5846957ebac5218aa2b49417fb7f9d8cf1"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": {}, "requires": {},
@ -169,19 +169,19 @@
}, },
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:035191ad6c7e8aed972e1374f4e0ecb38767c497fd6c961e4ae33898b62f78fb", "sha256:4cdaca9699a266936c04543700a5c6cdf52b563d33703812459cfe42c4c63ace",
"sha256:cd58563dd3f36d5909815752b12c80a2c510c051474f8296e28dbd3ef5634d65" "sha256:c8fbacb7d4e90a17cfe2a68e728c574e5b4a97ab66de417a44c373f7236366a1"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.20.11" "version": "==1.20.22"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:133fa0837762587fb4e5da3fb61ac0b45495cd9fd2d2be7679ba64899da1f3ba", "sha256:6738e87baa48e4befc447dded787fcadb87a23efb3a5ee6bfe78177bc9630516",
"sha256:497234f137810909289a600433cec5583ea8dc05a78b644653d76484138d78b9" "sha256:e66e4905dc048d5109df2cc6db55772b9111bfab8907557fa610f9241dca8752"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==1.23.11" "version": "==1.23.22"
}, },
"cachetools": { "cachetools": {
"hashes": [ "hashes": [
@ -298,11 +298,11 @@
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0", "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721",
"sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b" "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"
], ],
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==2.0.7" "version": "==2.0.9"
}, },
"click": { "click": {
"hashes": [ "hashes": [
@ -317,7 +317,7 @@
"sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667",
"sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"
], ],
"markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", "markers": "python_version < '4' and python_full_version >= '3.6.2'",
"version": "==0.3.0" "version": "==0.3.0"
}, },
"click-plugins": { "click-plugins": {
@ -416,21 +416,13 @@
"index": "pypi", "index": "pypi",
"version": "==0.7.1" "version": "==0.7.1"
}, },
"deprecated": {
"hashes": [
"sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d",
"sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.2.13"
},
"django": { "django": {
"hashes": [ "hashes": [
"sha256:51284300f1522ffcdb07ccbdf676a307c6678659e1284f0618e5a774127a6a08", "sha256:59304646ebc6a77b9b6a59adc67d51ecb03c5e3d63ed1f14c909cdfda84e8010",
"sha256:e22c9266da3eec7827737cde57694d7db801fedac938d252bf27377cec06ed1b" "sha256:d5a8a14da819a8b9237ee4d8c78dfe056ff6e8a7511987be627192225113ee75"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.2.9" "version": "==4.0"
}, },
"django-dbbackup": { "django-dbbackup": {
"git": "https://github.com/django-dbbackup/django-dbbackup.git", "git": "https://github.com/django-dbbackup/django-dbbackup.git",
@ -462,11 +454,11 @@
}, },
"django-otp": { "django-otp": {
"hashes": [ "hashes": [
"sha256:0c03a471db9e876f3671314bc9a65bd56a5c3c108ee0562c473701310bba4a77", "sha256:8637be826c0465d0fd1710e4472efe9fc83883853a2141fefdbace9358d20003",
"sha256:4c90cdaed683d736b0efafc034a3c6b410e1be2a53c24da287165b1f371d8776" "sha256:f002c71d4ea7f514590be00492980d3c87397b73dc20542e1c4fc00b66f2dda1"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.1.1" "version": "==1.1.3"
}, },
"django-prometheus": { "django-prometheus": {
"hashes": [ "hashes": [
@ -478,11 +470,11 @@
}, },
"django-redis": { "django-redis": {
"hashes": [ "hashes": [
"sha256:048f665bbe27f8ff2edebae6aa9c534ab137f1e8fa7234147ef470df3f3aa9b8", "sha256:98fb3d31633a1addea1aeb558a647359908bbcf78c0833f99496c5348fe3c1b4",
"sha256:97739ca9de3f964c51412d1d7d8aecdfd86737bb197fce6e1ff12620c63c97ee" "sha256:bf75bce0d6f65c3a6165dd6789506c8d22238f3bfaf7c4ad447e55afbc5b68cb"
], ],
"index": "pypi", "index": "pypi",
"version": "==5.0.0" "version": "==5.1.0"
}, },
"django-storages": { "django-storages": {
"hashes": [ "hashes": [
@ -540,6 +532,14 @@
"index": "pypi", "index": "pypi",
"version": "==3.1.0" "version": "==3.1.0"
}, },
"flower": {
"hashes": [
"sha256:2e17c4fb55c569508f3bfee7fe41f44b8362d30dbdf77b604a9d9f4740fe8cbd",
"sha256:a4fcf959881135303e98a74cc7533298b7dfeb48abcd1d90c5bd52cb789430a8"
],
"index": "pypi",
"version": "==1.0.0"
},
"frozenlist": { "frozenlist": {
"hashes": [ "hashes": [
"sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c", "sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c",
@ -699,23 +699,40 @@
}, },
"httptools": { "httptools": {
"hashes": [ "hashes": [
"sha256:01b392a166adcc8bc2f526a939a8aabf89fe079243e1543fd0e7dc1b58d737cb", "sha256:04114db99605c9b56ea22a8ec4d7b1485b908128ed4f4a8f6438489c428da794",
"sha256:200fc1cdf733a9ff554c0bb97a4047785cfaad9875307d6087001db3eb2b417f", "sha256:074afd8afdeec0fa6786cd4a1676e0c0be23dc9a017a86647efa6b695168104f",
"sha256:3ab1f390d8867f74b3b5ee2a7ecc9b8d7f53750bd45714bf1cb72a953d7dfa77", "sha256:113816f9af7dcfc4aa71ebb5354d77365f666ecf96ac7ff2aa1d24b6bca44165",
"sha256:78d03dd39b09c99ec917d50189e6743adbfd18c15d5944392d2eabda688bf149", "sha256:1a8f26327023fa1a947d36e60a0582149e182fbbc949c8a65ec8665754dbbe69",
"sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5", "sha256:2119fa619a4c53311f594f25c0205d619350fcb32140ec5057f861952e9b2b4f",
"sha256:80ffa04fe8c8dfacf6e4cef8277347d35b0442c581f5814f3b0cf41b65c43c6e", "sha256:21e948034f70e47c8abfa2d5e6f1a5661f87a2cddc7bcc70f61579cc87897c70",
"sha256:813871f961edea6cb2fe312f2d9b27d12a51ba92545380126f80d0de1917ea15", "sha256:32a10a5903b5bc0eb647d01cd1e95bec3bb614a9bf53f0af1e01360b2debdf81",
"sha256:94505026be56652d7a530ab03d89474dc6021019d6b8682281977163b3471ea0", "sha256:3787c1f46e9722ef7f07ea5c76b0103037483d1b12e34a02c53ceca5afa4e09a",
"sha256:a23166e5ae2775709cf4f7ad4c2048755ebfb272767d244e1a96d55ac775cca7", "sha256:3f82eb106e1474c63dba36a176067e65b48385f4cecddf3616411aa5d1fbdfec",
"sha256:a289c27ccae399a70eacf32df9a44059ca2ba4ac444604b00a19a6c1f0809943", "sha256:3f9b4856d46ba1f0c850f4e84b264a9a8b4460acb20e865ec00978ad9fbaa4cf",
"sha256:a7594f9a010cdf1e16a58b3bf26c9da39bbf663e3b8d46d39176999d71816658", "sha256:4137137de8976511a392e27bfdcf231bd926ac13d375e0414e927b08217d779e",
"sha256:b08d00d889a118f68f37f3c43e359aab24ee29eb2e3fe96d64c6a2ba8b9d6557", "sha256:4687dfc116a9f1eb22a7d797f0dc6f6e17190d406ca4e729634b38aa98044b17",
"sha256:cc9be041e428c10f8b6ab358c6b393648f9457094e1dcc11b4906026d43cd380", "sha256:47dba2345aaa01b87e4981e8756af441349340708d5b60712c98c55a4d28f4af",
"sha256:d5682eeb10cca0606c4a8286a3391d4c3c5a36f0c448e71b8bd05be4e1694bfb", "sha256:5a836bd85ae1fb4304f674808488dae403e136d274aa5bafd0e6ee456f11c371",
"sha256:fd3b8905e21431ad306eeaf56644a68fdd621bf8f3097eff54d0f6bdf7262065" "sha256:6e676bc3bb911b11f3d7e2144b9a53600bf6b9b21e0e4437aa308e1eef094d97",
"sha256:72ee0e3fb9c6437ab3ae34e9abee67fcee6876f4f58504e3f613dd5882aafdb7",
"sha256:79717080dc3f8b1eeb7f820b9b81528acbc04be6041f323fdd97550da2062575",
"sha256:8ac842df4fc3952efa7820b277961ea55e068bbc54cb59a0820400de7ae358d8",
"sha256:9f475b642c48b1b78584bdd12a5143e2c512485664331eade9c29ef769a17598",
"sha256:b8ac7dee63af4346e02b1e6d32202e3b5b3706a9928bec6da6d7a5b066217422",
"sha256:c0ac2e0ce6733c55858932e7d37fcc7b67ba6bb23e9648593c55f663de031b93",
"sha256:c14576b737d9e6e4f2a86af04918dbe9b62f57ce8102a8695c9a382dbe405c7f",
"sha256:cdc3975db86c29817e6d13df14e037c931fc893a710fb71097777a4147090068",
"sha256:eda95634027200f4b2a6d499e7c2e7fa9b8ee57e045dfda26958ea0af27c070b"
], ],
"version": "==0.2.0" "version": "==0.3.0"
},
"humanize": {
"hashes": [
"sha256:12f113f2e369dac7f35d3823f49262934f4a22a53a6d3d4c86b736f50db88c7b",
"sha256:a6f7cc1597db69a4e571ad5e19b4da07ee871da5a9de2b233dbfab02d98e9754"
],
"markers": "python_version >= '3.6'",
"version": "==3.13.1"
}, },
"hyperlink": { "hyperlink": {
"hashes": [ "hashes": [
@ -864,36 +881,42 @@
}, },
"msgpack": { "msgpack": {
"hashes": [ "hashes": [
"sha256:0cb94ee48675a45d3b86e61d13c1e6f1696f0183f0715544976356ff86f741d9", "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc",
"sha256:1026dcc10537d27dd2d26c327e552f05ce148977e9d7b9f1718748281b38c841", "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147",
"sha256:26a1759f1a88df5f1d0b393eb582ec022326994e311ba9c5818adc5374736439", "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3",
"sha256:2a5866bdc88d77f6e1370f82f2371c9bc6fc92fe898fa2dec0c5d4f5435a2694", "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba",
"sha256:31c17bbf2ae5e29e48d794c693b7ca7a0c73bd4280976d408c53df421e838d2a", "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39",
"sha256:497d2c12426adcd27ab83144057a705efb6acc7e85957a51d43cdcf7f258900f", "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85",
"sha256:5a9ee2540c78659a1dd0b110f73773533ee3108d4e1219b5a15a8d635b7aca0e", "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9",
"sha256:8521e5be9e3b93d4d5e07cb80b7e32353264d143c1f072309e1863174c6aadb1", "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a",
"sha256:87869ba567fe371c4555d2e11e4948778ab6b59d6cc9d8460d543e4cfbbddd1c", "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec",
"sha256:8ffb24a3b7518e843cd83538cf859e026d24ec41ac5721c18ed0c55101f9775b", "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88",
"sha256:92be4b12de4806d3c36810b0fe2aeedd8d493db39e2eb90742b9c09299eb5759", "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e",
"sha256:9ea52fff0473f9f3000987f313310208c879493491ef3ccf66268eff8d5a0326", "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a",
"sha256:a4355d2193106c7aa77c98fc955252a737d8550320ecdb2e9ac701e15e2943bc", "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b",
"sha256:a99b144475230982aee16b3d249170f1cccebf27fb0a08e9f603b69637a62192", "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1",
"sha256:ac25f3e0513f6673e8b405c3a80500eb7be1cf8f57584be524c4fa78fe8e0c83", "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3",
"sha256:b28c0876cce1466d7c2195d7658cf50e4730667196e2f1355c4209444717ee06", "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef",
"sha256:b55f7db883530b74c857e50e149126b91bb75d35c08b28db12dcb0346f15e46e", "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079",
"sha256:b6d9e2dae081aa35c44af9c4298de4ee72991305503442a5c74656d82b581fe9", "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52",
"sha256:c747c0cc08bd6d72a586310bda6ea72eeb28e7505990f342552315b229a19b33", "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a",
"sha256:d6c64601af8f3893d17ec233237030e3110f11b8a962cb66720bf70c0141aa54", "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a",
"sha256:d8167b84af26654c1124857d71650404336f4eb5cc06900667a493fc619ddd9f", "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4",
"sha256:de6bd7990a2c2dabe926b7e62a92886ccbf809425c347ae7de277067f97c2887", "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996",
"sha256:e36a812ef4705a291cdb4a2fd352f013134f26c6ff63477f20235138d1d21009", "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73",
"sha256:e89ec55871ed5473a041c0495b7b4e6099f6263438e0bd04ccd8418f92d5d7f2", "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a",
"sha256:f3e6aaf217ac1c7ce1563cf52a2f4f5d5b1f64e8729d794165db71da57257f0c", "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920",
"sha256:f484cd2dca68502de3704f056fa9b318c94b1539ed17a4c784266df5d6978c87", "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7",
"sha256:fae04496f5bc150eefad4e9571d1a76c55d021325dcd484ce45065ebbdd00984", "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d",
"sha256:fe07bc6735d08e492a327f496b7850e98cb4d112c56df69b0c844dbebcbb47f6" "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770",
"sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50",
"sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2",
"sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2",
"sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d",
"sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea",
"sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611"
], ],
"version": "==1.0.2" "version": "==1.0.3"
}, },
"multidict": { "multidict": {
"hashes": [ "hashes": [
@ -999,11 +1022,11 @@
}, },
"prompt-toolkit": { "prompt-toolkit": {
"hashes": [ "hashes": [
"sha256:449f333dd120bd01f5d296a8ce1452114ba3a71fae7288d2f0ae2c918764fa72", "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6",
"sha256:48d85cdca8b6c4f16480c7ce03fd193666b62b0a21667ca56b4bb5ad679d1170" "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506"
], ],
"markers": "python_full_version >= '3.6.2'", "markers": "python_full_version >= '3.6.2'",
"version": "==3.0.22" "version": "==3.0.24"
}, },
"psycopg2-binary": { "psycopg2-binary": {
"hashes": [ "hashes": [
@ -1093,39 +1116,39 @@
}, },
"pycryptodome": { "pycryptodome": {
"hashes": [ "hashes": [
"sha256:014c758af7fa38cab85b357a496b76f4fc9dda1f731eb28358d66fef7ad4a3e1", "sha256:1181c90d1a6aee68a84826825548d0db1b58d8541101f908d779d601d1690586",
"sha256:06162fcfed2f9deee8383fd59eaeabc7b7ffc3af50d3fad4000032deb8f700b0", "sha256:12c7343aec5a3b3df5c47265281b12b611f26ec9367b6129199d67da54b768c1",
"sha256:0ca7a6b4fc1f9fafe990b95c8cda89099797e2cfbf40e55607f2f2f5a3355dcb", "sha256:212c7f7fe11cad9275fbcff50ca977f1c6643f13560d081e7b0f70596df447b8",
"sha256:2a4bcc8a9977fee0979079cd33a9e9f0d3ddba5660d35ffe874cf84f1dd399d2", "sha256:32d15da81959faea6cbed95df2bb44f7f796211c110cf90b5ad3b2aeeb97fc8e",
"sha256:3c7ed5b07274535979c730daf5817db5e983ea80b04c22579eee8da4ca3ae4f8", "sha256:341c6bbf932c406b4f3ee2372e8589b67ac0cf4e99e7dc081440f43a3cde9f0f",
"sha256:4169ed515742425ff21e4bd3fabbb6994ffb64434472fb72230019bdfa36b939", "sha256:3558616f45d8584aee3eba27559bc6fd0ba9be6c076610ed3cc62bd5229ffdc3",
"sha256:428096bbf7a77e207f418dfd4d7c284df8ade81d2dc80f010e92753a3e406ad0", "sha256:39da5807aa1ff820799c928f745f89432908bf6624b9e981d2d7f9e55d91b860",
"sha256:4ce6b09547bf2c7cede3a017f79502eaed3e819c13cdb3cb357aea1b004e4cc6", "sha256:3f2f3dd596c6128d91314e60a6bcf4344610ef0e97f4ae4dd1770f86dd0748d8",
"sha256:53989477044be41fa4a63da09d5038c2a34b2f4554cfea2e3933b17186ee9e19", "sha256:4cded12e13785bbdf4ba1ff5fb9d261cd98162145f869e4fbc4a4b9083392f0b",
"sha256:621a90147a5e255fdc2a0fec2d56626b76b5d72ea9e60164c9a5a8976d45b0c9", "sha256:5a8c24d39d4a237dbfe181ea6593792bf9b5582c7fcfa7b8e0e12fda5eec07af",
"sha256:6db1f9fa1f52226621905f004278ce7bd90c8f5363ffd5d7ab3755363d98549a", "sha256:5d4264039a2087977f50072aaff2346d1c1c101cb359f9444cf92e3d1f42b4cd",
"sha256:6eda8a3157c91ba60b26a07bedd6c44ab8bda6cd79b6b5ea9744ba62c39b7b1e", "sha256:6bb0d340c93bcb674ea8899e2f6408ec64c6c21731a59481332b4b2a8143cc60",
"sha256:75e78360d1dd6d02eb288fd8275bb4d147d6e3f5337935c096d11dba1fa84748", "sha256:6f8f5b7b53516da7511951910ab458e799173722c91fea54e2ba2f56d102e4aa",
"sha256:7ff701fc283412e651eaab4319b3cd4eaa0827e94569cd37ee9075d5c05fe655", "sha256:90ad3381ccdc6a24cc2841e295706a168f32abefe64c679695712acac71fd5da",
"sha256:8f3a60926be78422e662b0d0b18351b426ce27657101c8a50bad80300de6a701", "sha256:93acad54a72d81253242eb0a15064be559ec9d989e5173286dc21cad19f01765",
"sha256:a843350d08c3d22f6c09c2f17f020d8dcfa59496165d7425a3fba0045543dda7", "sha256:9ea2f6674c803602a7c0437fccdc2ea036707e60456974fe26ca263bd501ec45",
"sha256:ae29fcd56152f417bfba50a36a56a7a5f9fb74ff80bab98704cac704de6568ab", "sha256:a6e1bcd9d5855f1a3c0f8d585f44c81b08f39a02754007f374fb8db9605ba29c",
"sha256:ae31cb874f6f0cedbed457c6374e7e54d7ed45c1a4e11a65a9c80968da90a650", "sha256:a78e4324e566b5fbc2b51e9240950d82fa9e1c7eb77acdf27f58712f65622c1d",
"sha256:b33c9b3d1327d821e28e9cc3a6512c14f8b17570ddb4cfb9a52247ed0fcc5d8b", "sha256:aceb1d217c3a025fb963849071446cf3aca1353282fe1c3cb7bd7339a4d47947",
"sha256:b59bf823cfafde8ef1105d8984f26d1694dff165adb7198b12e3e068d7999b15", "sha256:aed7eb4b64c600fbc5e6d4238991ad1b4179a558401f203d1fcbd24883748982",
"sha256:bc3c61ff92efdcc14af4a7b81da71d849c9acee51d8fd8ac9841a7620140d6c6", "sha256:b07a4238465eb8c65dd5df2ab8ba6df127e412293c0ed7656c003336f557a100",
"sha256:ce81b9c6aaa0f920e2ab05eb2b9f4ccd102e3016b2f37125593b16a83a4b0cc2", "sha256:b91404611767a7485837a6f1fd20cf9a5ae0ad362040a022cd65827ecb1b0d00",
"sha256:d7e5f6f692421e5219aa3b545eb0cffd832cd589a4b9dcd4a5eb4260e2c0d68a", "sha256:d8083de50f6dec56c3c6f270fb193590999583a1b27c9c75bc0b5cac22d438cc",
"sha256:da796e9221dda61a0019d01742337eb8a322de8598b678a4344ca0a436380315", "sha256:d845c587ceb82ac7cbac7d0bf8c62a1a0fe7190b028b322da5ca65f6e5a18b9e",
"sha256:ead516e03dfe062aefeafe4a29445a6449b0fc43bc8cb30194b2754917a63798", "sha256:db66ccda65d5d20c17b00768e462a86f6f540f9aea8419a7f76cc7d9effd82cd",
"sha256:ed45ef92d21db33685b789de2c015e9d9a18a74760a8df1fc152faee88cdf741", "sha256:dc88355c4b261ed259268e65705b28b44d99570337694d593f06e3b1698eaaf3",
"sha256:f19edd42368e9057c39492947bb99570dc927123e210008f2af7cf9b505c6892", "sha256:de0b711d673904dd6c65307ead36cb76622365a393569bf880895cba21195b7a",
"sha256:f9bad2220b80b4ed74f089db012ab5ab5419143a33fad6c8aedcc2a9341eac70", "sha256:e05f994f30f1cda3cbe57441f41220d16731cf99d868bb02a8f6484c454c206b",
"sha256:fce7e22d96030b35345637c563246c24d4513bd3b413e1c40293114837ab8912", "sha256:e80f7469b0b3ea0f694230477d8501dc5a30a717e94fddd4821e6721f3053eae",
"sha256:ffd0cac13ff41f2d15ed39dc6ba1d2ad88dd2905d656c33d8235852f5d6151fd" "sha256:f699360ae285fcae9c8f53ca6acf33796025a82bb0ccd7c1c551b04c1726def3"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.11.0" "version": "==3.12.0"
}, },
"pydantic": { "pydantic": {
"hashes": [ "hashes": [
@ -1268,11 +1291,11 @@
}, },
"redis": { "redis": {
"hashes": [ "hashes": [
"sha256:c8481cf414474e3497ec7971a1ba9b998c8efad0f0d289a009a5bbef040894f9", "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2",
"sha256:ccf692811f2c1fc7a92b466aa2599e4a6d2d73d5f736a2c70be600657c0da34a" "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==4.0.2" "version": "==3.5.3"
}, },
"requests": { "requests": {
"hashes": [ "hashes": [
@ -1293,11 +1316,11 @@
}, },
"rsa": { "rsa": {
"hashes": [ "hashes": [
"sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2", "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17",
"sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9" "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==4.7.2" "version": "==4.8"
}, },
"s3transfer": { "s3transfer": {
"hashes": [ "hashes": [
@ -1325,11 +1348,11 @@
}, },
"setuptools": { "setuptools": {
"hashes": [ "hashes": [
"sha256:157d21de9d055ab9e8ea3186d91e7f4f865e11f42deafa952d90842671fc2576", "sha256:6d10741ff20b89cd8c6a536ee9dc90d3002dec0226c78fb98605bfb9ef8a7adf",
"sha256:4adde3d1e1c89bde1c643c64d89cdd94cbfd8c75252ee459d4500bccb9c7d05d" "sha256:d144f85102f999444d06f9c0e8c737fd0194f10f2f7e5fdb77573f6e2fa4fad0"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==59.2.0" "version": "==59.5.0"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -1349,11 +1372,11 @@
}, },
"structlog": { "structlog": {
"hashes": [ "hashes": [
"sha256:063216becff8e6f6558122a9b00734f7e50bfef309eb730c85a52c74ed861a96", "sha256:305a66201f9605a2e8a2595271a446f258175901c09c01e4c2c2a8ac5b68edf1",
"sha256:4da2aec0aebf6dee7beb884eb0fda26ed9d6cce5338fcd523e8597d0f1826746" "sha256:6ed8fadb27cf8362be0e606f5e79ccdd3b1e879aac65f9dc0ac3033fd013a7be"
], ],
"index": "pypi", "index": "pypi",
"version": "==21.3.0" "version": "==21.4.0"
}, },
"swagger-spec-validator": { "swagger-spec-validator": {
"hashes": [ "hashes": [
@ -1363,8 +1386,54 @@
"index": "pypi", "index": "pypi",
"version": "==2.7.4" "version": "==2.7.4"
}, },
"tornado": {
"hashes": [
"sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb",
"sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c",
"sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288",
"sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95",
"sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558",
"sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe",
"sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791",
"sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d",
"sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326",
"sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b",
"sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4",
"sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c",
"sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910",
"sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5",
"sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c",
"sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0",
"sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675",
"sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd",
"sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f",
"sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c",
"sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea",
"sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6",
"sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05",
"sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd",
"sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575",
"sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a",
"sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37",
"sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795",
"sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f",
"sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32",
"sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c",
"sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01",
"sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4",
"sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2",
"sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921",
"sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085",
"sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df",
"sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102",
"sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5",
"sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68",
"sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"
],
"markers": "python_version >= '3.5'",
"version": "==6.1"
},
"twisted": { "twisted": {
"extras": [],
"hashes": [ "hashes": [
"sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b",
"sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006"
@ -1382,11 +1451,11 @@
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e",
"sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9" "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==4.0.0" "version": "==4.0.1"
}, },
"ua-parser": { "ua-parser": {
"hashes": [ "hashes": [
@ -1420,11 +1489,11 @@
"standard" "standard"
], ],
"hashes": [ "hashes": [
"sha256:17f898c64c71a2640514d4089da2689e5db1ce5d4086c2d53699bf99513421c1", "sha256:d8c839231f270adaa6d338d525e2652a0b4a5f4c2430b5c4ef6ae4d11776b0d2",
"sha256:d9a3c0dd1ca86728d3e235182683b4cf94cd53a867c288eaeca80ee781b2caff" "sha256:eacb66afa65e0648fcbce5e746b135d09722231ffffc61883d4fac2b62fbea8d"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.15.0" "version": "==0.16.0"
}, },
"uvloop": { "uvloop": {
"hashes": [ "hashes": [
@ -1479,11 +1548,11 @@
}, },
"websocket-client": { "websocket-client": {
"hashes": [ "hashes": [
"sha256:0133d2f784858e59959ce82ddac316634229da55b498aac311f1620567a710ec", "sha256:1315816c0acc508997eb3ae03b9d3ff619c9d12d544c9a9b553704b1cc4f6af5",
"sha256:8dfb715d8a992f5712fff8c843adae94e22b22a99b2c5e6b0ec4a1a981cc4e0d" "sha256:2eed4cc58e4d65613ed6114af2f380f7910ff416fc8c46947f6e76b6815f56c0"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==1.2.1" "version": "==1.2.3"
}, },
"websockets": { "websockets": {
"hashes": [ "hashes": [
@ -1538,63 +1607,6 @@
], ],
"version": "==10.1" "version": "==10.1"
}, },
"wrapt": {
"hashes": [
"sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179",
"sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096",
"sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374",
"sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df",
"sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185",
"sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785",
"sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7",
"sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909",
"sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918",
"sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33",
"sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068",
"sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829",
"sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af",
"sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79",
"sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce",
"sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc",
"sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36",
"sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade",
"sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca",
"sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32",
"sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125",
"sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e",
"sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709",
"sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f",
"sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b",
"sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb",
"sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb",
"sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489",
"sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640",
"sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb",
"sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851",
"sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d",
"sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44",
"sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13",
"sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2",
"sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb",
"sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b",
"sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9",
"sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755",
"sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c",
"sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a",
"sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf",
"sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3",
"sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229",
"sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e",
"sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de",
"sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554",
"sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10",
"sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80",
"sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056",
"sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==1.13.3"
},
"xmlsec": { "xmlsec": {
"hashes": [ "hashes": [
"sha256:135724cdce60e6bbd072fca6f09a21f72e2cecc59eebb4eed7740c316ecabc7b", "sha256:135724cdce60e6bbd072fca6f09a21f72e2cecc59eebb4eed7740c316ecabc7b",
@ -1751,11 +1763,11 @@
"develop": { "develop": {
"astroid": { "astroid": {
"hashes": [ "hashes": [
"sha256:5f6f75e45f15290e73b56f9dfde95b4bf96382284cde406ef4203e928335a495", "sha256:5939cf55de24b92bda00345d4d0659d01b3c7dafb5055165c330bc7c568ba273",
"sha256:cd8326b424c971e7d87678609cf6275d22028afd37d6ac59c16d47f1245882f6" "sha256:776ca0b748b4ad69c00bfe0fff38fa2d21c338e12c84aa9715ee0d473c422778"
], ],
"markers": "python_version ~= '3.6'", "markers": "python_version ~= '3.6'",
"version": "==2.8.6" "version": "==2.9.0"
}, },
"async-generator": { "async-generator": {
"hashes": [ "hashes": [
@ -1861,11 +1873,11 @@
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0", "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721",
"sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b" "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"
], ],
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==2.0.7" "version": "==2.0.9"
}, },
"click": { "click": {
"hashes": [ "hashes": [
@ -1888,56 +1900,56 @@
"toml" "toml"
], ],
"hashes": [ "hashes": [
"sha256:046647b96969fda1ae0605f61288635209dd69dcd27ba3ec0bf5148bc157f954", "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0",
"sha256:06d009e8a29483cbc0520665bc46035ffe9ae0e7484a49f9782c2a716e37d0a0", "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd",
"sha256:0cde7d9fe2fb55ff68ebe7fb319ef188e9b88e0a3d1c9c5db7dd829cd93d2193", "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884",
"sha256:1de9c6f5039ee2b1860b7bad2c7bc3651fbeb9368e4c4d93e98a76358cdcb052", "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48",
"sha256:24ed38ec86754c4d5a706fbd5b52b057c3df87901a8610d7e5642a08ec07087e", "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76",
"sha256:27a3df08a855522dfef8b8635f58bab81341b2fb5f447819bc252da3aa4cf44c", "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0",
"sha256:310c40bed6b626fd1f463e5a83dba19a61c4eb74e1ac0d07d454ebbdf9047e9d", "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64",
"sha256:3348865798c077c695cae00da0924136bb5cc501f236cfd6b6d9f7a3c94e0ec4", "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685",
"sha256:35b246ae3a2c042dc8f410c94bcb9754b18179cdb81ff9477a9089dbc9ecc186", "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47",
"sha256:3f546f48d5d80a90a266769aa613bc0719cb3e9c2ef3529d53f463996dd15a9d", "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d",
"sha256:586d38dfc7da4a87f5816b203ff06dd7c1bb5b16211ccaa0e9788a8da2b93696", "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840",
"sha256:5d3855d5d26292539861f5ced2ed042fc2aa33a12f80e487053aed3bcb6ced13", "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f",
"sha256:610c0ba11da8de3a753dc4b1f71894f9f9debfdde6559599f303286e70aeb0c2", "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971",
"sha256:62646d98cf0381ffda301a816d6ac6c35fc97aa81b09c4c52d66a15c4bef9d7c", "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c",
"sha256:66af99c7f7b64d050d37e795baadf515b4561124f25aae6e1baa482438ecc388", "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a",
"sha256:675adb3b3380967806b3cbb9c5b00ceb29b1c472692100a338730c1d3e59c8b9", "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de",
"sha256:6e5a8c947a2a89c56655ecbb789458a3a8e3b0cbf4c04250331df8f647b3de59", "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17",
"sha256:7a39590d1e6acf6a3c435c5d233f72f5d43b585f5be834cff1f21fec4afda225", "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4",
"sha256:80cb70264e9a1d04b519cdba3cd0dc42847bf8e982a4d55c769b9b0ee7cdce1e", "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521",
"sha256:82fdcb64bf08aa5db881db061d96db102c77397a570fbc112e21c48a4d9cb31b", "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57",
"sha256:8492d37acdc07a6eac6489f6c1954026f2260a85a4c2bb1e343fe3d35f5ee21a", "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b",
"sha256:94f558f8555e79c48c422045f252ef41eb43becdd945e9c775b45ebfc0cbd78f", "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282",
"sha256:958ac66272ff20e63d818627216e3d7412fdf68a2d25787b89a5c6f1eb7fdd93", "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644",
"sha256:95a58336aa111af54baa451c33266a8774780242cab3704b7698d5e514840758", "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475",
"sha256:96129e41405887a53a9cc564f960d7f853cc63d178f3a182fdd302e4cab2745b", "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d",
"sha256:97ef6e9119bd39d60ef7b9cd5deea2b34869c9f0b9777450a7e3759c1ab09b9b", "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da",
"sha256:98d44a8136eebbf544ad91fef5bd2b20ef0c9b459c65a833c923d9aa4546b204", "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953",
"sha256:9d2c2e3ce7b8cc932a2f918186964bd44de8c84e2f9ef72dc616f5bb8be22e71", "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2",
"sha256:a300b39c3d5905686c75a369d2a66e68fd01472ea42e16b38c948bd02b29e5bd", "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e",
"sha256:a34fccb45f7b2d890183a263578d60a392a1a218fdc12f5bce1477a6a68d4373", "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c",
"sha256:a4d48e42e17d3de212f9af44f81ab73b9378a4b2b8413fd708d0d9023f2bbde4", "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc",
"sha256:af45eea024c0e3a25462fade161afab4f0d9d9e0d5a5d53e86149f74f0a35ecc", "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64",
"sha256:ba6125d4e55c0b8e913dad27b22722eac7abdcb1f3eab1bd090eee9105660266", "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74",
"sha256:bc1ee1318f703bc6c971da700d74466e9b86e0c443eb85983fb2a1bd20447263", "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617",
"sha256:c18725f3cffe96732ef96f3de1939d81215fd6d7d64900dcc4acfe514ea4fcbf", "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3",
"sha256:c8e9c4bcaaaa932be581b3d8b88b677489975f845f7714efc8cce77568b6711c", "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d",
"sha256:cc799916b618ec9fd00135e576424165691fec4f70d7dc12cfaef09268a2478c", "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa",
"sha256:cd2d11a59afa5001ff28073ceca24ae4c506da4355aba30d1e7dd2bd0d2206dc", "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739",
"sha256:d0a595a781f8e186580ff8e3352dd4953b1944289bec7705377c80c7e36c4d6c", "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8",
"sha256:d3c5f49ce6af61154060640ad3b3281dbc46e2e0ef2fe78414d7f8a324f0b649", "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8",
"sha256:d9a635114b88c0ab462e0355472d00a180a5fbfd8511e7f18e4ac32652e7d972", "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781",
"sha256:e5432d9c329b11c27be45ee5f62cf20a33065d482c8dec1941d6670622a6fb8f", "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58",
"sha256:eab14fdd410500dae50fd14ccc332e65543e7b39f6fc076fe90603a0e5d2f929", "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9",
"sha256:ebcc03e1acef4ff44f37f3c61df478d6e469a573aa688e5a162f85d7e4c3860d", "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c",
"sha256:fae3fe111670e51f1ebbc475823899524e3459ea2db2cb88279bbfb2a0b8a3de", "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd",
"sha256:fd92ece726055e80d4e3f01fff3b91f54b18c9c357c48fcf6119e87e2461a091", "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e",
"sha256:ffa545230ca2ad921ad066bf8fd627e7be43716b6e0fcf8e32af1b8188ccb0ab" "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"
], ],
"index": "pypi", "index": "pypi",
"version": "==6.1.2" "version": "==6.2"
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
@ -2127,11 +2139,11 @@
}, },
"pylint": { "pylint": {
"hashes": [ "hashes": [
"sha256:0f358e221c45cbd4dad2a1e4b883e75d28acdcccd29d40c76eb72b307269b126", "sha256:9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9",
"sha256:2c9843fff1a88ca0ad98a256806c82c5a8f86086e7ccbdb93297d86c3f90c436" "sha256:daabda3f7ed9d1c60f52d563b1b854632fd90035bcf01443e234d3dc794e3b74"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.11.1" "version": "==2.12.2"
}, },
"pylint-django": { "pylint-django": {
"hashes": [ "hashes": [
@ -2173,19 +2185,19 @@
}, },
"pytest-django": { "pytest-django": {
"hashes": [ "hashes": [
"sha256:65783e78382456528bd9d79a35843adde9e6a47347b20464eb2c885cb0f1f606", "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e",
"sha256:b5171e3798bf7e3fc5ea7072fe87324db67a4dd9f1192b037fed4cc3c1b7f455" "sha256:d9076f759bb7c36939dbdd5ae6633c18edfc2902d1a69fdbefd2426b970ce6c2"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.4.0" "version": "==4.5.2"
}, },
"pytest-randomly": { "pytest-randomly": {
"hashes": [ "hashes": [
"sha256:2c0a332c4b124e372e2473803bcc91ec87797664f4955afef2b844c0021662b1", "sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1",
"sha256:cbd5c50b7c41491c202c71a3df33a75619d610a4f5c34aa2bd02ac30fce7cd43" "sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.10.2" "version": "==3.10.3"
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
@ -2228,23 +2240,38 @@
}, },
"regex": { "regex": {
"hashes": [ "hashes": [
"sha256:0416f7399e918c4b0e074a0f66e5191077ee2ca32a0f99d4c187a62beb47aa05",
"sha256:05b7d6d7e64efe309972adab77fc2af8907bb93217ec60aa9fe12a0dad35874f", "sha256:05b7d6d7e64efe309972adab77fc2af8907bb93217ec60aa9fe12a0dad35874f",
"sha256:0617383e2fe465732af4509e61648b77cbe3aee68b6ac8c0b6fe934db90be5cc", "sha256:0617383e2fe465732af4509e61648b77cbe3aee68b6ac8c0b6fe934db90be5cc",
"sha256:07856afef5ffcc052e7eccf3213317fbb94e4a5cd8177a2caa69c980657b3cb4", "sha256:07856afef5ffcc052e7eccf3213317fbb94e4a5cd8177a2caa69c980657b3cb4",
"sha256:0f594b96fe2e0821d026365f72ac7b4f0b487487fb3d4aaf10dd9d97d88a9737",
"sha256:139a23d1f5d30db2cc6c7fd9c6d6497872a672db22c4ae1910be22d4f4b2068a",
"sha256:162abfd74e88001d20cb73ceaffbfe601469923e875caf9118333b1a4aaafdc4", "sha256:162abfd74e88001d20cb73ceaffbfe601469923e875caf9118333b1a4aaafdc4",
"sha256:2207ae4f64ad3af399e2d30dde66f0b36ae5c3129b52885f1bffc2f05ec505c8", "sha256:2207ae4f64ad3af399e2d30dde66f0b36ae5c3129b52885f1bffc2f05ec505c8",
"sha256:2409b5c9cef7054dde93a9803156b411b677affc84fca69e908b1cb2c540025d",
"sha256:2fee3ed82a011184807d2127f1733b4f6b2ff6ec7151d83ef3477f3b96a13d03",
"sha256:30ab804ea73972049b7a2a5c62d97687d69b5a60a67adca07eb73a0ddbc9e29f", "sha256:30ab804ea73972049b7a2a5c62d97687d69b5a60a67adca07eb73a0ddbc9e29f",
"sha256:3598893bde43091ee5ca0a6ad20f08a0435e93a69255eeb5f81b85e81e329264",
"sha256:3b5df18db1fccd66de15aa59c41e4f853b5df7550723d26aa6cb7f40e5d9da5a", "sha256:3b5df18db1fccd66de15aa59c41e4f853b5df7550723d26aa6cb7f40e5d9da5a",
"sha256:3c5fb32cc6077abad3bbf0323067636d93307c9fa93e072771cf9a64d1c0f3ef", "sha256:3c5fb32cc6077abad3bbf0323067636d93307c9fa93e072771cf9a64d1c0f3ef",
"sha256:416c5f1a188c91e3eb41e9c8787288e707f7d2ebe66e0a6563af280d9b68478f", "sha256:416c5f1a188c91e3eb41e9c8787288e707f7d2ebe66e0a6563af280d9b68478f",
"sha256:42b50fa6666b0d50c30a990527127334d6b96dd969011e843e726a64011485da",
"sha256:432bd15d40ed835a51617521d60d0125867f7b88acf653e4ed994a1f8e4995dc", "sha256:432bd15d40ed835a51617521d60d0125867f7b88acf653e4ed994a1f8e4995dc",
"sha256:473e67837f786404570eae33c3b64a4b9635ae9f00145250851a1292f484c063",
"sha256:4aaa4e0705ef2b73dd8e36eeb4c868f80f8393f5f4d855e94025ce7ad8525f50", "sha256:4aaa4e0705ef2b73dd8e36eeb4c868f80f8393f5f4d855e94025ce7ad8525f50",
"sha256:50a7ddf3d131dc5633dccdb51417e2d1910d25cbcf842115a3a5893509140a3a",
"sha256:529801a0d58809b60b3531ee804d3e3be4b412c94b5d267daa3de7fadef00f49",
"sha256:537ca6a3586931b16a85ac38c08cc48f10fc870a5b25e51794c74df843e9966d", "sha256:537ca6a3586931b16a85ac38c08cc48f10fc870a5b25e51794c74df843e9966d",
"sha256:53db2c6be8a2710b359bfd3d3aa17ba38f8aa72a82309a12ae99d3c0c3dcd74d", "sha256:53db2c6be8a2710b359bfd3d3aa17ba38f8aa72a82309a12ae99d3c0c3dcd74d",
"sha256:5537f71b6d646f7f5f340562ec4c77b6e1c915f8baae822ea0b7e46c1f09b733", "sha256:5537f71b6d646f7f5f340562ec4c77b6e1c915f8baae822ea0b7e46c1f09b733",
"sha256:563d5f9354e15e048465061509403f68424fef37d5add3064038c2511c8f5e00",
"sha256:5d408a642a5484b9b4d11dea15a489ea0928c7e410c7525cd892f4d04f2f617b",
"sha256:61600a7ca4bcf78a96a68a27c2ae9389763b5b94b63943d5158f2a377e09d29a",
"sha256:6650f16365f1924d6014d2ea770bde8555b4a39dc9576abb95e3cd1ff0263b36", "sha256:6650f16365f1924d6014d2ea770bde8555b4a39dc9576abb95e3cd1ff0263b36",
"sha256:666abff54e474d28ff42756d94544cdfd42e2ee97065857413b72e8a2d6a6345", "sha256:666abff54e474d28ff42756d94544cdfd42e2ee97065857413b72e8a2d6a6345",
"sha256:68a067c11463de2a37157930d8b153005085e42bcb7ad9ca562d77ba7d1404e0", "sha256:68a067c11463de2a37157930d8b153005085e42bcb7ad9ca562d77ba7d1404e0",
"sha256:6e1d2cc79e8dae442b3fa4a26c5794428b98f81389af90623ffcc650ce9f6732",
"sha256:74cbeac0451f27d4f50e6e8a8f3a52ca074b5e2da9f7b505c4201a57a8ed6286",
"sha256:780b48456a0f0ba4d390e8b5f7c661fdd218934388cde1a974010a965e200e12", "sha256:780b48456a0f0ba4d390e8b5f7c661fdd218934388cde1a974010a965e200e12",
"sha256:788aef3549f1924d5c38263104dae7395bf020a42776d5ec5ea2b0d3d85d6646", "sha256:788aef3549f1924d5c38263104dae7395bf020a42776d5ec5ea2b0d3d85d6646",
"sha256:7ee1227cf08b6716c85504aebc49ac827eb88fcc6e51564f010f11a406c0a667", "sha256:7ee1227cf08b6716c85504aebc49ac827eb88fcc6e51564f010f11a406c0a667",
@ -2254,24 +2281,34 @@
"sha256:9345b6f7ee578bad8e475129ed40123d265464c4cfead6c261fd60fc9de00bcf", "sha256:9345b6f7ee578bad8e475129ed40123d265464c4cfead6c261fd60fc9de00bcf",
"sha256:93a5051fcf5fad72de73b96f07d30bc29665697fb8ecdfbc474f3452c78adcf4", "sha256:93a5051fcf5fad72de73b96f07d30bc29665697fb8ecdfbc474f3452c78adcf4",
"sha256:962b9a917dd7ceacbe5cd424556914cb0d636001e393b43dc886ba31d2a1e449", "sha256:962b9a917dd7ceacbe5cd424556914cb0d636001e393b43dc886ba31d2a1e449",
"sha256:96fc32c16ea6d60d3ca7f63397bff5c75c5a562f7db6dec7d412f7c4d2e78ec0",
"sha256:98ba568e8ae26beb726aeea2273053c717641933836568c2a0278a84987b2a1a", "sha256:98ba568e8ae26beb726aeea2273053c717641933836568c2a0278a84987b2a1a",
"sha256:a3feefd5e95871872673b08636f96b61ebef62971eab044f5124fb4dea39919d", "sha256:a3feefd5e95871872673b08636f96b61ebef62971eab044f5124fb4dea39919d",
"sha256:a955b747d620a50408b7fdf948e04359d6e762ff8a85f5775d907ceced715129",
"sha256:b43c2b8a330a490daaef5a47ab114935002b13b3f9dc5da56d5322ff218eeadb", "sha256:b43c2b8a330a490daaef5a47ab114935002b13b3f9dc5da56d5322ff218eeadb",
"sha256:b483c9d00a565633c87abd0aaf27eb5016de23fed952e054ecc19ce32f6a9e7e", "sha256:b483c9d00a565633c87abd0aaf27eb5016de23fed952e054ecc19ce32f6a9e7e",
"sha256:b9ed0b1e5e0759d6b7f8e2f143894b2a7f3edd313f38cf44e1e15d360e11749b",
"sha256:ba05430e819e58544e840a68b03b28b6d328aff2e41579037e8bab7653b37d83", "sha256:ba05430e819e58544e840a68b03b28b6d328aff2e41579037e8bab7653b37d83",
"sha256:ca49e1ab99593438b204e00f3970e7a5f70d045267051dfa6b5f4304fcfa1dbf",
"sha256:ca5f18a75e1256ce07494e245cdb146f5a9267d3c702ebf9b65c7f8bd843431e", "sha256:ca5f18a75e1256ce07494e245cdb146f5a9267d3c702ebf9b65c7f8bd843431e",
"sha256:cd410a1cbb2d297c67d8521759ab2ee3f1d66206d2e4328502a487589a2cb21b",
"sha256:ce298e3d0c65bd03fa65ffcc6db0e2b578e8f626d468db64fdf8457731052942",
"sha256:d5ca078bb666c4a9d1287a379fe617a6dccd18c3e8a7e6c7e1eb8974330c626a", "sha256:d5ca078bb666c4a9d1287a379fe617a6dccd18c3e8a7e6c7e1eb8974330c626a",
"sha256:d5fd67df77bab0d3f4ea1d7afca9ef15c2ee35dfb348c7b57ffb9782a6e4db6e",
"sha256:da1a90c1ddb7531b1d5ff1e171b4ee61f6345119be7351104b67ff413843fe94", "sha256:da1a90c1ddb7531b1d5ff1e171b4ee61f6345119be7351104b67ff413843fe94",
"sha256:dba70f30fd81f8ce6d32ddeef37d91c8948e5d5a4c63242d16a2b2df8143aafc", "sha256:dba70f30fd81f8ce6d32ddeef37d91c8948e5d5a4c63242d16a2b2df8143aafc",
"sha256:dc07f021ee80510f3cd3af2cad5b6a3b3a10b057521d9e6aaeb621730d320c5a",
"sha256:dd33eb9bdcfbabab3459c9ee651d94c842bc8a05fabc95edf4ee0c15a072495e", "sha256:dd33eb9bdcfbabab3459c9ee651d94c842bc8a05fabc95edf4ee0c15a072495e",
"sha256:e0538c43565ee6e703d3a7c3bdfe4037a5209250e8502c98f20fea6f5fdf2965", "sha256:e0538c43565ee6e703d3a7c3bdfe4037a5209250e8502c98f20fea6f5fdf2965",
"sha256:e1f54b9b4b6c53369f40028d2dd07a8c374583417ee6ec0ea304e710a20f80a0", "sha256:e1f54b9b4b6c53369f40028d2dd07a8c374583417ee6ec0ea304e710a20f80a0",
"sha256:e32d2a2b02ccbef10145df9135751abea1f9f076e67a4e261b05f24b94219e36", "sha256:e32d2a2b02ccbef10145df9135751abea1f9f076e67a4e261b05f24b94219e36",
"sha256:e6096b0688e6e14af6a1b10eaad86b4ff17935c49aa774eac7c95a57a4e8c296",
"sha256:e71255ba42567d34a13c03968736c5d39bb4a97ce98188fafb27ce981115beec", "sha256:e71255ba42567d34a13c03968736c5d39bb4a97ce98188fafb27ce981115beec",
"sha256:ed2e07c6a26ed4bea91b897ee2b0835c21716d9a469a96c3e878dc5f8c55bb23", "sha256:ed2e07c6a26ed4bea91b897ee2b0835c21716d9a469a96c3e878dc5f8c55bb23",
"sha256:eef2afb0fd1747f33f1ee3e209bce1ed582d1896b240ccc5e2697e3275f037c7", "sha256:eef2afb0fd1747f33f1ee3e209bce1ed582d1896b240ccc5e2697e3275f037c7",
"sha256:f23222527b307970e383433daec128d769ff778d9b29343fb3496472dc20dabe", "sha256:f23222527b307970e383433daec128d769ff778d9b29343fb3496472dc20dabe",
"sha256:f341ee2df0999bfdf7a95e448075effe0db212a59387de1a70690e4acb03d4c6", "sha256:f341ee2df0999bfdf7a95e448075effe0db212a59387de1a70690e4acb03d4c6",
"sha256:f5be7805e53dafe94d295399cfbe5227f39995a997f4fd8539bf3cbdc8f47ca8",
"sha256:f7f325be2804246a75a4f45c72d4ce80d2443ab815063cdf70ee8fb2ca59ee1b", "sha256:f7f325be2804246a75a4f45c72d4ce80d2443ab815063cdf70ee8fb2ca59ee1b",
"sha256:f8af619e3be812a2059b212064ea7a640aff0568d972cd1b9e920837469eb3cb", "sha256:f8af619e3be812a2059b212064ea7a640aff0568d972cd1b9e920837469eb3cb",
"sha256:fa8c626d6441e2d04b6ee703ef2d1e17608ad44c7cb75258c09dd42bacdfc64b", "sha256:fa8c626d6441e2d04b6ee703ef2d1e17608ad44c7cb75258c09dd42bacdfc64b",
@ -2305,11 +2342,11 @@
}, },
"setuptools": { "setuptools": {
"hashes": [ "hashes": [
"sha256:157d21de9d055ab9e8ea3186d91e7f4f865e11f42deafa952d90842671fc2576", "sha256:6d10741ff20b89cd8c6a536ee9dc90d3002dec0226c78fb98605bfb9ef8a7adf",
"sha256:4adde3d1e1c89bde1c643c64d89cdd94cbfd8c75252ee459d4500bccb9c7d05d" "sha256:d144f85102f999444d06f9c0e8c737fd0194f10f2f7e5fdb77573f6e2fa4fad0"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==59.2.0" "version": "==59.5.0"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -2384,11 +2421,11 @@
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed", "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e",
"sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9" "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==4.0.0" "version": "==4.0.1"
}, },
"urllib3": { "urllib3": {
"extras": [ "extras": [

View file

@ -11,7 +11,12 @@ from structlog.stdlib import get_logger
from authentik import ENV_GIT_HASH_KEY, __version__ from authentik import ENV_GIT_HASH_KEY, __version__
from authentik.events.models import Event, EventAction, Notification from authentik.events.models import Event, EventAction, Notification
from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import (
MonitoredTask,
TaskResult,
TaskResultStatus,
prefill_task,
)
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.lib.utils.http import get_http_session from authentik.lib.utils.http import get_http_session
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
@ -48,8 +53,9 @@ def clear_update_notifications():
notification.delete() notification.delete()
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def update_latest_version(self: PrefilledMonitoredTask): @prefill_task
def update_latest_version(self: MonitoredTask):
"""Update latest version info""" """Update latest version info"""
if CONFIG.y_bool("disable_update_check"): if CONFIG.y_bool("disable_update_check"):
cache.set(VERSION_CACHE_KEY, "0.0.0", VERSION_CACHE_TIMEOUT) cache.set(VERSION_CACHE_KEY, "0.0.0", VERSION_CACHE_TIMEOUT)

View file

@ -314,7 +314,7 @@ class UserViewSet(UsedByMixin, ModelViewSet):
name=username, name=username,
attributes={USER_ATTRIBUTE_SA: True, USER_ATTRIBUTE_TOKEN_EXPIRING: False}, attributes={USER_ATTRIBUTE_SA: True, USER_ATTRIBUTE_TOKEN_EXPIRING: False},
) )
if create_group: if create_group and self.request.user.has_perm("authentik_core.add_group"):
group = Group.objects.create( group = Group.objects.create(
name=username, name=username,
) )

View file

@ -65,4 +65,6 @@ def structlog_add_request_id(logger: Logger, method_name: str, event_dict: dict)
"""If threadlocal has authentik defined, add request_id to log""" """If threadlocal has authentik defined, add request_id to log"""
if hasattr(LOCAL, "authentik"): if hasattr(LOCAL, "authentik"):
event_dict.update(LOCAL.authentik) event_dict.update(LOCAL.authentik)
if hasattr(LOCAL, "authentik_task"):
event_dict.update(LOCAL.authentik_task)
return event_dict return event_dict

View file

@ -25,7 +25,6 @@ from structlog.stdlib import get_logger
from authentik.core.exceptions import PropertyMappingExpressionException from authentik.core.exceptions import PropertyMappingExpressionException
from authentik.core.signals import password_changed from authentik.core.signals import password_changed
from authentik.core.types import UILoginButton, UserSettingSerializer from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.flows.models import Flow
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.lib.generators import generate_id from authentik.lib.generators import generate_id
from authentik.lib.models import CreatedUpdatedModel, DomainlessURLValidator, SerializerModel from authentik.lib.models import CreatedUpdatedModel, DomainlessURLValidator, SerializerModel
@ -203,7 +202,7 @@ class Provider(SerializerModel):
name = models.TextField() name = models.TextField()
authorization_flow = models.ForeignKey( authorization_flow = models.ForeignKey(
Flow, "authentik_flows.Flow",
on_delete=models.CASCADE, on_delete=models.CASCADE,
help_text=_("Flow used when authorizing this provider."), help_text=_("Flow used when authorizing this provider."),
related_name="provider_authorization", related_name="provider_authorization",
@ -263,7 +262,7 @@ class Application(PolicyBindingModel):
it is returned as-is""" it is returned as-is"""
if not self.meta_icon: if not self.meta_icon:
return None return None
if self.meta_icon.name.startswith("http") or self.meta_icon.name.startswith("/static"): if "://" in self.meta_icon.name or self.meta_icon.name.startswith("/static"):
return self.meta_icon.name return self.meta_icon.name
return self.meta_icon.url return self.meta_icon.url
@ -324,7 +323,7 @@ class Source(ManagedModel, SerializerModel, PolicyBindingModel):
property_mappings = models.ManyToManyField("PropertyMapping", default=None, blank=True) property_mappings = models.ManyToManyField("PropertyMapping", default=None, blank=True)
authentication_flow = models.ForeignKey( authentication_flow = models.ForeignKey(
Flow, "authentik_flows.Flow",
blank=True, blank=True,
null=True, null=True,
default=None, default=None,
@ -333,7 +332,7 @@ class Source(ManagedModel, SerializerModel, PolicyBindingModel):
related_name="source_authentication", related_name="source_authentication",
) )
enrollment_flow = models.ForeignKey( enrollment_flow = models.ForeignKey(
Flow, "authentik_flows.Flow",
blank=True, blank=True,
null=True, null=True,
default=None, default=None,

View file

@ -16,15 +16,21 @@ from kubernetes.config.incluster_config import SERVICE_HOST_ENV_NAME
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.core.models import AuthenticatedSession, ExpiringModel from authentik.core.models import AuthenticatedSession, ExpiringModel
from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import (
MonitoredTask,
TaskResult,
TaskResultStatus,
prefill_task,
)
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
LOGGER = get_logger() LOGGER = get_logger()
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def clean_expired_models(self: PrefilledMonitoredTask): @prefill_task
def clean_expired_models(self: MonitoredTask):
"""Remove expired objects""" """Remove expired objects"""
messages = [] messages = []
for cls in ExpiringModel.__subclasses__(): for cls in ExpiringModel.__subclasses__():
@ -62,8 +68,9 @@ def should_backup() -> bool:
return True return True
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def backup_database(self: PrefilledMonitoredTask): # pragma: no cover @prefill_task
def backup_database(self: MonitoredTask): # pragma: no cover
"""Database backup""" """Database backup"""
self.result_timeout_hours = 25 self.result_timeout_hours = 25
if not should_backup(): if not should_backup():

View file

@ -192,7 +192,7 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
secret=certificate, secret=certificate,
type="certificate", type="certificate",
).from_http(request) ).from_http(request)
if "download" in request._request.GET: if "download" in request.query_params:
# Mime type from https://pki-tutorial.readthedocs.io/en/latest/mime.html # Mime type from https://pki-tutorial.readthedocs.io/en/latest/mime.html
response = HttpResponse( response = HttpResponse(
certificate.certificate_data, content_type="application/x-pem-file" certificate.certificate_data, content_type="application/x-pem-file"
@ -223,7 +223,7 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
secret=certificate, secret=certificate,
type="private_key", type="private_key",
).from_http(request) ).from_http(request)
if "download" in request._request.GET: if "download" in request.query_params:
# Mime type from https://pki-tutorial.readthedocs.io/en/latest/mime.html # Mime type from https://pki-tutorial.readthedocs.io/en/latest/mime.html
response = HttpResponse(certificate.key_data, content_type="application/x-pem-file") response = HttpResponse(certificate.key_data, content_type="application/x-pem-file")
response[ response[

View file

@ -6,7 +6,12 @@ from django.utils.translation import gettext_lazy as _
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import (
MonitoredTask,
TaskResult,
TaskResultStatus,
prefill_task,
)
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
@ -15,8 +20,9 @@ LOGGER = get_logger()
MANAGED_DISCOVERED = "goauthentik.io/crypto/discovered/%s" MANAGED_DISCOVERED = "goauthentik.io/crypto/discovered/%s"
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def certificate_discovery(self: PrefilledMonitoredTask): @prefill_task
def certificate_discovery(self: MonitoredTask):
"""Discover and update certificates form the filesystem""" """Discover and update certificates form the filesystem"""
certs = {} certs = {}
private_keys = {} private_keys = {}

View file

@ -186,31 +186,21 @@ class MonitoredTask(Task):
raise NotImplementedError raise NotImplementedError
class PrefilledMonitoredTask(MonitoredTask): def prefill_task(func):
"""Subclass of MonitoredTask, but create entry in cache if task hasn't been run """Ensure a task's details are always in cache, so it can always be triggered via API"""
Does not support UID""" status = TaskInfo.by_name(func.__name__)
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
status = TaskInfo.by_name(self.__name__)
if status: if status:
return return func
TaskInfo( TaskInfo(
task_name=self.__name__, task_name=func.__name__,
task_description=self.__doc__, task_description=func.__doc__,
result=TaskResult(TaskResultStatus.UNKNOWN, messages=[_("Task has not been run yet.")]), result=TaskResult(TaskResultStatus.UNKNOWN, messages=[_("Task has not been run yet.")]),
task_call_module=self.__module__, task_call_module=func.__module__,
task_call_func=self.__name__, task_call_func=func.__name__,
# We don't have real values for these attributes but they cannot be null # We don't have real values for these attributes but they cannot be null
start_timestamp=default_timer(), start_timestamp=default_timer(),
finish_timestamp=default_timer(), finish_timestamp=default_timer(),
finish_time=datetime.now(), finish_time=datetime.now(),
).save(86400) ).save(86400)
LOGGER.debug("prefilled task", task_name=self.__name__) LOGGER.debug("prefilled task", task_name=func.__name__)
return func
def run(self, *args, **kwargs):
raise NotImplementedError
for task in TaskInfo.all().values():
task.set_prom_metrics()

View file

@ -0,0 +1,46 @@
# Generated by Django 3.2.9 on 2021-12-05 13:50
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0018_auto_20210330_1345_squashed_0028_alter_token_intent"),
(
"authentik_flows",
"0019_alter_flow_background_squashed_0024_alter_flow_compatibility_mode",
),
]
operations = [
migrations.CreateModel(
name="FlowToken",
fields=[
(
"token_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="authentik_core.token",
),
),
("_plan", models.TextField()),
(
"flow",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="authentik_flows.flow"
),
),
],
options={
"verbose_name": "Flow Token",
"verbose_name_plural": "Flow Tokens",
},
bases=("authentik_core.token",),
),
]

View file

@ -1,4 +1,6 @@
"""Flow models""" """Flow models"""
from base64 import b64decode, b64encode
from pickle import dumps, loads # nosec
from typing import TYPE_CHECKING, Optional, Type from typing import TYPE_CHECKING, Optional, Type
from uuid import uuid4 from uuid import uuid4
@ -9,11 +11,13 @@ from model_utils.managers import InheritanceManager
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.core.models import Token
from authentik.core.types import UserSettingSerializer from authentik.core.types import UserSettingSerializer
from authentik.lib.models import InheritanceForeignKey, SerializerModel from authentik.lib.models import InheritanceForeignKey, SerializerModel
from authentik.policies.models import PolicyBindingModel from authentik.policies.models import PolicyBindingModel
if TYPE_CHECKING: if TYPE_CHECKING:
from authentik.flows.planner import FlowPlan
from authentik.flows.stage import StageView from authentik.flows.stage import StageView
LOGGER = get_logger() LOGGER = get_logger()
@ -260,3 +264,30 @@ class ConfigurableStage(models.Model):
class Meta: class Meta:
abstract = True abstract = True
class FlowToken(Token):
"""Subclass of a standard Token, stores the currently active flow plan upon creation.
Can be used to later resume a flow."""
flow = models.ForeignKey(Flow, on_delete=models.CASCADE)
_plan = models.TextField()
@staticmethod
def pickle(plan) -> str:
"""Pickle into string"""
data = dumps(plan)
return b64encode(data).decode()
@property
def plan(self) -> "FlowPlan":
"""Load Flow plan from pickled version"""
return loads(b64decode(self._plan.encode())) # nosec
def __str__(self) -> str:
return f"Flow Token {super.__str__()}"
class Meta:
verbose_name = _("Flow Token")
verbose_name_plural = _("Flow Tokens")

View file

@ -24,6 +24,9 @@ PLAN_CONTEXT_SSO = "is_sso"
PLAN_CONTEXT_REDIRECT = "redirect" PLAN_CONTEXT_REDIRECT = "redirect"
PLAN_CONTEXT_APPLICATION = "application" PLAN_CONTEXT_APPLICATION = "application"
PLAN_CONTEXT_SOURCE = "source" PLAN_CONTEXT_SOURCE = "source"
# Is set by the Flow Planner when a FlowToken was used, and the currently active flow plan
# was restored.
PLAN_CONTEXT_IS_RESTORED = "is_restored"
GAUGE_FLOWS_CACHED = UpdatingGauge( GAUGE_FLOWS_CACHED = UpdatingGauge(
"authentik_flows_cached", "authentik_flows_cached",
"Cached flows", "Cached flows",

View file

@ -34,8 +34,16 @@ from authentik.flows.challenge import (
WithUserInfoChallenge, WithUserInfoChallenge,
) )
from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException
from authentik.flows.models import ConfigurableStage, Flow, FlowDesignation, FlowStageBinding, Stage from authentik.flows.models import (
ConfigurableStage,
Flow,
FlowDesignation,
FlowStageBinding,
FlowToken,
Stage,
)
from authentik.flows.planner import ( from authentik.flows.planner import (
PLAN_CONTEXT_IS_RESTORED,
PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_PENDING_USER,
PLAN_CONTEXT_REDIRECT, PLAN_CONTEXT_REDIRECT,
FlowPlan, FlowPlan,
@ -55,6 +63,7 @@ SESSION_KEY_APPLICATION_PRE = "authentik_flows_application_pre"
SESSION_KEY_GET = "authentik_flows_get" SESSION_KEY_GET = "authentik_flows_get"
SESSION_KEY_POST = "authentik_flows_post" SESSION_KEY_POST = "authentik_flows_post"
SESSION_KEY_HISTORY = "authentik_flows_history" SESSION_KEY_HISTORY = "authentik_flows_history"
QS_KEY_TOKEN = "flow_token" # nosec
def challenge_types(): def challenge_types():
@ -127,8 +136,31 @@ class FlowExecutorView(APIView):
message = exc.__doc__ if exc.__doc__ else str(exc) message = exc.__doc__ if exc.__doc__ else str(exc)
return self.stage_invalid(error_message=message) return self.stage_invalid(error_message=message)
def _check_flow_token(self, get_params: QueryDict):
"""Check if the user is using a flow token to restore a plan"""
tokens = FlowToken.filter_not_expired(key=get_params[QS_KEY_TOKEN])
if not tokens.exists():
return False
token: FlowToken = tokens.first()
try:
plan = token.plan
except (AttributeError, EOFError, ImportError, IndexError) as exc:
LOGGER.warning("f(exec): Failed to restore token plan", exc=exc)
finally:
token.delete()
if not isinstance(plan, FlowPlan):
return None
plan.context[PLAN_CONTEXT_IS_RESTORED] = True
self._logger.debug("f(exec): restored flow plan from token", plan=plan)
return plan
# pylint: disable=unused-argument, too-many-return-statements # pylint: disable=unused-argument, too-many-return-statements
def dispatch(self, request: HttpRequest, flow_slug: str) -> HttpResponse: def dispatch(self, request: HttpRequest, flow_slug: str) -> HttpResponse:
get_params = QueryDict(request.GET.get("query", ""))
if QS_KEY_TOKEN in get_params:
plan = self._check_flow_token(get_params)
if plan:
self.request.session[SESSION_KEY_PLAN] = plan
# Early check if there's an active Plan for the current session # Early check if there's an active Plan for the current session
if SESSION_KEY_PLAN in self.request.session: if SESSION_KEY_PLAN in self.request.session:
self.plan = self.request.session[SESSION_KEY_PLAN] self.plan = self.request.session[SESSION_KEY_PLAN]
@ -156,7 +188,7 @@ class FlowExecutorView(APIView):
# we don't show an error message here, but rather call _flow_done() # we don't show an error message here, but rather call _flow_done()
return self._flow_done() return self._flow_done()
# Initial flow request, check if we have an upstream query string passed in # Initial flow request, check if we have an upstream query string passed in
request.session[SESSION_KEY_GET] = QueryDict(request.GET.get("query", "")) request.session[SESSION_KEY_GET] = get_params
# We don't save the Plan after getting the next stage # We don't save the Plan after getting the next stage
# as it hasn't been successfully passed yet # as it hasn't been successfully passed yet
try: try:

View file

@ -2,12 +2,18 @@
from django.db import DatabaseError from django.db import DatabaseError
from authentik.core.tasks import CELERY_APP from authentik.core.tasks import CELERY_APP
from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import (
MonitoredTask,
TaskResult,
TaskResultStatus,
prefill_task,
)
from authentik.managed.manager import ObjectManager from authentik.managed.manager import ObjectManager
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def managed_reconcile(self: PrefilledMonitoredTask): @prefill_task
def managed_reconcile(self: MonitoredTask):
"""Run ObjectManager to ensure objects are up-to-date""" """Run ObjectManager to ensure objects are up-to-date"""
try: try:
ObjectManager().run() ObjectManager().run()

View file

@ -1,6 +1,8 @@
"""Outpost API Views""" """Outpost API Views"""
from dacite.core import from_dict from dacite.core import from_dict
from dacite.exceptions import DaciteError from dacite.exceptions import DaciteError
from django_filters.filters import ModelMultipleChoiceFilter
from django_filters.filterset import FilterSet
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import BooleanField, CharField, DateTimeField from rest_framework.fields import BooleanField, CharField, DateTimeField
@ -99,16 +101,30 @@ class OutpostHealthSerializer(PassiveSerializer):
version_outdated = BooleanField(read_only=True) version_outdated = BooleanField(read_only=True)
class OutpostFilter(FilterSet):
"""Filter for Outposts"""
providers_by_pk = ModelMultipleChoiceFilter(
field_name="providers",
queryset=Provider.objects.all(),
)
class Meta:
model = Outpost
fields = {
"providers": ["isnull"],
"name": ["iexact", "icontains"],
"service_connection__name": ["iexact", "icontains"],
}
class OutpostViewSet(UsedByMixin, ModelViewSet): class OutpostViewSet(UsedByMixin, ModelViewSet):
"""Outpost Viewset""" """Outpost Viewset"""
queryset = Outpost.objects.all() queryset = Outpost.objects.all()
serializer_class = OutpostSerializer serializer_class = OutpostSerializer
filterset_fields = { filterset_class = OutpostFilter
"providers": ["isnull"],
"name": ["iexact", "icontains"],
"service_connection__name": ["iexact", "icontains"],
}
search_fields = [ search_fields = [
"name", "name",
"providers__name", "providers__name",

View file

@ -19,9 +19,9 @@ from structlog.stdlib import get_logger
from authentik.events.monitored_tasks import ( from authentik.events.monitored_tasks import (
MonitoredTask, MonitoredTask,
PrefilledMonitoredTask,
TaskResult, TaskResult,
TaskResultStatus, TaskResultStatus,
prefill_task,
) )
from authentik.lib.utils.reflection import path_to_class from authentik.lib.utils.reflection import path_to_class
from authentik.outposts.controllers.base import BaseController, ControllerException from authentik.outposts.controllers.base import BaseController, ControllerException
@ -75,8 +75,9 @@ def outpost_service_connection_state(connection_pk: Any):
cache.set(connection.state_key, state, timeout=None) cache.set(connection.state_key, state, timeout=None)
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def outpost_service_connection_monitor(self: PrefilledMonitoredTask): @prefill_task
def outpost_service_connection_monitor(self: MonitoredTask):
"""Regularly check the state of Outpost Service Connections""" """Regularly check the state of Outpost Service Connections"""
connections = OutpostServiceConnection.objects.all() connections = OutpostServiceConnection.objects.all()
for connection in connections.iterator(): for connection in connections.iterator():
@ -124,8 +125,9 @@ def outpost_controller(
self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, logs)) self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, logs))
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def outpost_token_ensurer(self: PrefilledMonitoredTask): @prefill_task
def outpost_token_ensurer(self: MonitoredTask):
"""Periodically ensure that all Outposts have valid Service Accounts """Periodically ensure that all Outposts have valid Service Accounts
and Tokens""" and Tokens"""
all_outposts = Outpost.objects.all() all_outposts = Outpost.objects.all()

View file

@ -11,6 +11,8 @@ from authentik.flows.planner import PLAN_CONTEXT_SSO
from authentik.lib.expression.evaluator import BaseEvaluator from authentik.lib.expression.evaluator import BaseEvaluator
from authentik.lib.utils.http import get_client_ip from authentik.lib.utils.http import get_client_ip
from authentik.policies.exceptions import PolicyException from authentik.policies.exceptions import PolicyException
from authentik.policies.models import Policy, PolicyBinding
from authentik.policies.process import PolicyProcess
from authentik.policies.types import PolicyRequest, PolicyResult from authentik.policies.types import PolicyRequest, PolicyResult
LOGGER = get_logger() LOGGER = get_logger()
@ -31,6 +33,7 @@ class PolicyEvaluator(BaseEvaluator):
self._context["ak_logger"] = get_logger(policy_name) self._context["ak_logger"] = get_logger(policy_name)
self._context["ak_message"] = self.expr_func_message self._context["ak_message"] = self.expr_func_message
self._context["ak_user_has_authenticator"] = self.expr_func_user_has_authenticator self._context["ak_user_has_authenticator"] = self.expr_func_user_has_authenticator
self._context["ak_call_policy"] = self.expr_func_call_policy
self._context["ip_address"] = ip_address self._context["ip_address"] = ip_address
self._context["ip_network"] = ip_network self._context["ip_network"] = ip_network
self._filename = policy_name or "PolicyEvaluator" self._filename = policy_name or "PolicyEvaluator"
@ -39,6 +42,16 @@ class PolicyEvaluator(BaseEvaluator):
"""Wrapper to append to messages list, which is returned with PolicyResult""" """Wrapper to append to messages list, which is returned with PolicyResult"""
self._messages.append(message) self._messages.append(message)
def expr_func_call_policy(self, name: str, **kwargs) -> PolicyResult:
"""Call policy by name, with current request"""
policy = Policy.objects.filter(name=name).select_subclasses().first()
if not policy:
raise ValueError(f"Policy '{name}' not found.")
req: PolicyRequest = self._context["request"]
req.context.update(kwargs)
proc = PolicyProcess(PolicyBinding(policy=policy), request=req, connection=None)
return proc.profiling_wrapper()
def expr_func_user_has_authenticator( def expr_func_user_has_authenticator(
self, user: User, device_type: Optional[str] = None self, user: User, device_type: Optional[str] = None
) -> bool: ) -> bool:

View file

@ -127,8 +127,8 @@ class PolicyProcess(PROCESS_CLASS):
) )
return policy_result return policy_result
def run(self): # pragma: no cover def profiling_wrapper(self):
"""Task wrapper to run policy checking""" """Run with profiling enabled"""
with Hub.current.start_span( with Hub.current.start_span(
op="policy.process.execute", op="policy.process.execute",
) as span, HIST_POLICIES_EXECUTION_TIME.labels( ) as span, HIST_POLICIES_EXECUTION_TIME.labels(
@ -142,8 +142,12 @@ class PolicyProcess(PROCESS_CLASS):
span: Span span: Span
span.set_data("policy", self.binding.policy) span.set_data("policy", self.binding.policy)
span.set_data("request", self.request) span.set_data("request", self.request)
return self.execute()
def run(self): # pragma: no cover
"""Task wrapper to run policy checking"""
try: try:
self.connection.send(self.execute()) self.connection.send(self.profiling_wrapper())
except Exception as exc: # pylint: disable=broad-except except Exception as exc: # pylint: disable=broad-except
LOGGER.warning(str(exc)) LOGGER.warning(str(exc))
self.connection.send(PolicyResult(False, str(exc))) self.connection.send(PolicyResult(False, str(exc)))

View file

@ -2,7 +2,12 @@
from django.core.cache import cache from django.core.cache import cache
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import (
MonitoredTask,
TaskResult,
TaskResultStatus,
prefill_task,
)
from authentik.policies.reputation.models import IPReputation, UserReputation from authentik.policies.reputation.models import IPReputation, UserReputation
from authentik.policies.reputation.signals import CACHE_KEY_IP_PREFIX, CACHE_KEY_USER_PREFIX from authentik.policies.reputation.signals import CACHE_KEY_IP_PREFIX, CACHE_KEY_USER_PREFIX
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
@ -10,8 +15,9 @@ from authentik.root.celery import CELERY_APP
LOGGER = get_logger() LOGGER = get_logger()
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def save_ip_reputation(self: PrefilledMonitoredTask): @prefill_task
def save_ip_reputation(self: MonitoredTask):
"""Save currently cached reputation to database""" """Save currently cached reputation to database"""
objects_to_update = [] objects_to_update = []
for key, score in cache.get_many(cache.keys(CACHE_KEY_IP_PREFIX + "*")).items(): for key, score in cache.get_many(cache.keys(CACHE_KEY_IP_PREFIX + "*")).items():
@ -23,8 +29,9 @@ def save_ip_reputation(self: PrefilledMonitoredTask):
self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Successfully updated IP Reputation"])) self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Successfully updated IP Reputation"]))
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def save_user_reputation(self: PrefilledMonitoredTask): @prefill_task
def save_user_reputation(self: MonitoredTask):
"""Save currently cached reputation to database""" """Save currently cached reputation to database"""
objects_to_update = [] objects_to_update = []
for key, score in cache.get_many(cache.keys(CACHE_KEY_USER_PREFIX + "*")).items(): for key, score in cache.get_many(cache.keys(CACHE_KEY_USER_PREFIX + "*")).items():

View file

@ -97,7 +97,7 @@ class TokenParams:
) )
# https://tools.ietf.org/html/rfc6749#section-6 # https://tools.ietf.org/html/rfc6749#section-6
# Fallback to original token's scopes when none are given # Fallback to original token's scopes when none are given
if self.scope == []: if not self.scope:
self.scope = self.refresh_token.scope self.scope = self.refresh_token.scope
except RefreshToken.DoesNotExist: except RefreshToken.DoesNotExist:
LOGGER.warning( LOGGER.warning(

View file

@ -36,6 +36,7 @@ from authentik.flows.models import Flow, FlowDesignation
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
from authentik.providers.saml.processors.metadata import MetadataProcessor from authentik.providers.saml.processors.metadata import MetadataProcessor
from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser
from authentik.sources.saml.processors.constants import SAML_BINDING_POST, SAML_BINDING_REDIRECT
LOGGER = get_logger() LOGGER = get_logger()
@ -109,7 +110,17 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
name="download", name="download",
location=OpenApiParameter.QUERY, location=OpenApiParameter.QUERY,
type=OpenApiTypes.BOOL, type=OpenApiTypes.BOOL,
) ),
OpenApiParameter(
name="force_binding",
location=OpenApiParameter.QUERY,
type=OpenApiTypes.STR,
enum=[
SAML_BINDING_REDIRECT,
SAML_BINDING_POST,
],
description=("Optionally force the metadata to only include one binding."),
),
], ],
) )
@action(methods=["GET"], detail=True, permission_classes=[AllowAny]) @action(methods=["GET"], detail=True, permission_classes=[AllowAny])
@ -122,8 +133,10 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
except ValueError: except ValueError:
raise Http404 raise Http404
try: try:
metadata = MetadataProcessor(provider, request).build_entity_descriptor() proc = MetadataProcessor(provider, request)
if "download" in request._request.GET: proc.force_binding = request.query_params.get("force_binding", None)
metadata = proc.build_entity_descriptor()
if "download" in request.query_params:
response = HttpResponse(metadata, content_type="application/xml") response = HttpResponse(metadata, content_type="application/xml")
response[ response[
"Content-Disposition" "Content-Disposition"

View file

@ -101,7 +101,8 @@ class AssertionProcessor:
attribute_statement.append(attribute) attribute_statement.append(attribute)
except PropertyMappingExpressionException as exc: except (PropertyMappingExpressionException, ValueError) as exc:
# Value error can be raised when assigning invalid data to an attribute
Event.new( Event.new(
EventAction.CONFIGURATION_ERROR, EventAction.CONFIGURATION_ERROR,
message=f"Failed to evaluate property-mapping: {str(exc)}", message=f"Failed to evaluate property-mapping: {str(exc)}",

View file

@ -29,10 +29,12 @@ class MetadataProcessor:
provider: SAMLProvider provider: SAMLProvider
http_request: HttpRequest http_request: HttpRequest
force_binding: Optional[str]
def __init__(self, provider: SAMLProvider, request: HttpRequest): def __init__(self, provider: SAMLProvider, request: HttpRequest):
self.provider = provider self.provider = provider
self.http_request = request self.http_request = request
self.force_binding = None
self.xml_id = get_random_id() self.xml_id = get_random_id()
def get_signing_key_descriptor(self) -> Optional[Element]: def get_signing_key_descriptor(self) -> Optional[Element]:
@ -79,6 +81,8 @@ class MetadataProcessor:
), ),
} }
for binding, url in binding_url_map.items(): for binding, url in binding_url_map.items():
if self.force_binding and self.force_binding != binding:
continue
element = Element(f"{{{NS_SAML_METADATA}}}SingleSignOnService") element = Element(f"{{{NS_SAML_METADATA}}}SingleSignOnService")
element.attrib["Binding"] = binding element.attrib["Binding"] = binding
element.attrib["Location"] = url element.attrib["Location"] = url

View file

@ -125,7 +125,7 @@ class SAMLSSOBindingPOSTView(SAMLSSOView):
# This happens when using POST bindings but the user isn't logged in # This happens when using POST bindings but the user isn't logged in
# (user gets redirected and POST body is 'lost') # (user gets redirected and POST body is 'lost')
if SESSION_KEY_POST in self.request.session: if SESSION_KEY_POST in self.request.session:
payload = self.request.session[SESSION_KEY_POST] payload = self.request.session.pop(SESSION_KEY_POST)
if REQUEST_KEY_SAML_REQUEST not in payload: if REQUEST_KEY_SAML_REQUEST not in payload:
LOGGER.info("check_saml_request: SAML payload missing") LOGGER.info("check_saml_request: SAML payload missing")
return bad_request_message(self.request, "The SAML request payload is missing.") return bad_request_message(self.request, "The SAML request payload is missing.")

View file

@ -14,6 +14,7 @@ from celery.signals import (
from django.conf import settings from django.conf import settings
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.core.middleware import LOCAL
from authentik.lib.sentry import before_send from authentik.lib.sentry import before_send
from authentik.lib.utils.errors import exception_to_string from authentik.lib.utils.errors import exception_to_string
@ -26,7 +27,7 @@ CELERY_APP = Celery("authentik")
# pylint: disable=unused-argument # pylint: disable=unused-argument
@setup_logging.connect @setup_logging.connect
def config_loggers(*args, **kwags): def config_loggers(*args, **kwargs):
"""Apply logging settings from settings.py to celery""" """Apply logging settings from settings.py to celery"""
dictConfig(settings.LOGGING) dictConfig(settings.LOGGING)
@ -41,8 +42,12 @@ def after_task_publish_hook(sender=None, headers=None, body=None, **kwargs):
# pylint: disable=unused-argument # pylint: disable=unused-argument
@task_prerun.connect @task_prerun.connect
def task_prerun_hook(task_id, task, *args, **kwargs): def task_prerun_hook(task_id: str, task, *args, **kwargs):
"""Log task_id on worker""" """Log task_id on worker"""
request_id = "task-" + task_id.replace("-", "")
LOCAL.authentik_task = {
"request_id": request_id,
}
LOGGER.debug("Task started", task_id=task_id, task_name=task.__name__) LOGGER.debug("Task started", task_id=task_id, task_name=task.__name__)
@ -51,6 +56,10 @@ def task_prerun_hook(task_id, task, *args, **kwargs):
def task_postrun_hook(task_id, task, *args, retval=None, state=None, **kwargs): def task_postrun_hook(task_id, task, *args, retval=None, state=None, **kwargs):
"""Log task_id on worker""" """Log task_id on worker"""
LOGGER.debug("Task finished", task_id=task_id, task_name=task.__name__, state=state) LOGGER.debug("Task finished", task_id=task_id, task_name=task.__name__, state=state)
if not hasattr(LOCAL, "authentik_task"):
return
for key in list(LOCAL.authentik_task.keys()):
del LOCAL.authentik_task[key]
# pylint: disable=unused-argument # pylint: disable=unused-argument

View file

@ -1,4 +1,6 @@
"""Integrate ./manage.py test with pytest""" """Integrate ./manage.py test with pytest"""
from argparse import ArgumentParser
from django.conf import settings from django.conf import settings
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
@ -8,10 +10,20 @@ from tests.e2e.utils import get_docker_tag
class PytestTestRunner: # pragma: no cover class PytestTestRunner: # pragma: no cover
"""Runs pytest to discover and run tests.""" """Runs pytest to discover and run tests."""
def __init__(self, verbosity=1, failfast=False, keepdb=False, **_): def __init__(self, verbosity=1, failfast=False, keepdb=False, **kwargs):
self.verbosity = verbosity self.verbosity = verbosity
self.failfast = failfast self.failfast = failfast
self.keepdb = keepdb self.keepdb = keepdb
self.args = ["-vv"]
if self.failfast:
self.args.append("--exitfirst")
if self.keepdb:
self.args.append("--reuse-db")
if kwargs.get("randomly_seed", None):
self.args.append(f"--randomly-seed={kwargs['randomly_seed']}")
settings.TEST = True settings.TEST = True
settings.CELERY_TASK_ALWAYS_EAGER = True settings.CELERY_TASK_ALWAYS_EAGER = True
CONFIG.y_set("authentik.avatars", "none") CONFIG.y_set("authentik.avatars", "none")
@ -21,21 +33,20 @@ class PytestTestRunner: # pragma: no cover
f"goauthentik.io/dev-%(type)s:{get_docker_tag()}", f"goauthentik.io/dev-%(type)s:{get_docker_tag()}",
) )
@classmethod
def add_arguments(cls, parser: ArgumentParser):
"""Add more pytest-specific arguments"""
parser.add_argument("--randomly-seed", type=int)
def run_tests(self, test_labels): def run_tests(self, test_labels):
"""Run pytest and return the exitcode. """Run pytest and return the exitcode.
It translates some of Django's test command option to pytest's. It translates some of Django's test command option to pytest's.
""" """
import pytest import pytest
argv = ["-vv"]
if self.failfast:
argv.append("--exitfirst")
if self.keepdb:
argv.append("--reuse-db")
if any("tests/e2e" in label for label in test_labels): if any("tests/e2e" in label for label in test_labels):
argv.append("-pno:randomly") self.args.append("-pno:randomly")
self.args.extend(test_labels)
argv.extend(test_labels) return pytest.main(self.args)
return pytest.main(argv)

View file

@ -1,10 +1,9 @@
"""OAuth Source Serializer""" """OAuth Source Serializer"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions from authentik.api.authorization import OwnerFilter, OwnerSuperuserPermissions
from authentik.core.api.sources import SourceSerializer from authentik.core.api.sources import SourceSerializer
from authentik.core.api.used_by import UsedByMixin from authentik.core.api.used_by import UsedByMixin
from authentik.sources.oauth.models import UserOAuthSourceConnection from authentik.sources.oauth.models import UserOAuthSourceConnection
@ -15,30 +14,19 @@ class UserOAuthSourceConnectionSerializer(SourceSerializer):
class Meta: class Meta:
model = UserOAuthSourceConnection model = UserOAuthSourceConnection
fields = [ fields = ["pk", "user", "source", "identifier", "access_token"]
"pk",
"user",
"source",
"identifier",
]
extra_kwargs = { extra_kwargs = {
"user": {"read_only": True}, "user": {"read_only": True},
"access_token": {"write_only": True},
} }
class UserOAuthSourceConnectionViewSet( class UserOAuthSourceConnectionViewSet(UsedByMixin, ModelViewSet):
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""Source Viewset""" """Source Viewset"""
queryset = UserOAuthSourceConnection.objects.all() queryset = UserOAuthSourceConnection.objects.all()
serializer_class = UserOAuthSourceConnectionSerializer serializer_class = UserOAuthSourceConnectionSerializer
filterset_fields = ["source__slug"] filterset_fields = ["source__slug"]
permission_classes = [OwnerPermissions] permission_classes = [OwnerSuperuserPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter] filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
ordering = ["source__slug"] ordering = ["source__slug"]

View file

@ -1,10 +1,9 @@
"""Plex Source connection Serializer""" """Plex Source connection Serializer"""
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions from authentik.api.authorization import OwnerFilter, OwnerSuperuserPermissions
from authentik.core.api.sources import SourceSerializer from authentik.core.api.sources import SourceSerializer
from authentik.core.api.used_by import UsedByMixin from authentik.core.api.used_by import UsedByMixin
from authentik.sources.plex.models import PlexSourceConnection from authentik.sources.plex.models import PlexSourceConnection
@ -27,19 +26,12 @@ class PlexSourceConnectionSerializer(SourceSerializer):
} }
class PlexSourceConnectionViewSet( class PlexSourceConnectionViewSet(UsedByMixin, ModelViewSet):
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""Plex Source connection Serializer""" """Plex Source connection Serializer"""
queryset = PlexSourceConnection.objects.all() queryset = PlexSourceConnection.objects.all()
serializer_class = PlexSourceConnectionSerializer serializer_class = PlexSourceConnectionSerializer
filterset_fields = ["source__slug"] filterset_fields = ["source__slug"]
permission_classes = [OwnerPermissions] permission_classes = [OwnerSuperuserPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter] filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
ordering = ["pk"] ordering = ["pk"]

View file

@ -3,7 +3,12 @@ from django.utils.timezone import now
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.core.models import AuthenticatedSession, User from authentik.core.models import AuthenticatedSession, User
from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.events.monitored_tasks import (
MonitoredTask,
TaskResult,
TaskResultStatus,
prefill_task,
)
from authentik.lib.utils.time import timedelta_from_string from authentik.lib.utils.time import timedelta_from_string
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
from authentik.sources.saml.models import SAMLSource from authentik.sources.saml.models import SAMLSource
@ -11,8 +16,9 @@ from authentik.sources.saml.models import SAMLSource
LOGGER = get_logger() LOGGER = get_logger()
@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def clean_temporary_users(self: PrefilledMonitoredTask): @prefill_task
def clean_temporary_users(self: MonitoredTask):
"""Remove temporary users created by SAML Sources""" """Remove temporary users created by SAML Sources"""
_now = now() _now = now()
messages = [] messages = []

View file

@ -12,17 +12,16 @@ from rest_framework.fields import CharField
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.core.models import Token
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.models import FlowToken
from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED, PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import SESSION_KEY_GET from authentik.flows.views.executor import QS_KEY_TOKEN, SESSION_KEY_GET
from authentik.stages.email.models import EmailStage from authentik.stages.email.models import EmailStage
from authentik.stages.email.tasks import send_mails from authentik.stages.email.tasks import send_mails
from authentik.stages.email.utils import TemplateEmailMessage from authentik.stages.email.utils import TemplateEmailMessage
LOGGER = get_logger() LOGGER = get_logger()
QS_KEY_TOKEN = "etoken" # nosec
PLAN_CONTEXT_EMAIL_SENT = "email_sent" PLAN_CONTEXT_EMAIL_SENT = "email_sent"
@ -56,7 +55,7 @@ class EmailStageView(ChallengeStageView):
relative_url = f"{base_url}?{urlencode(kwargs)}" relative_url = f"{base_url}?{urlencode(kwargs)}"
return self.request.build_absolute_uri(relative_url) return self.request.build_absolute_uri(relative_url)
def get_token(self) -> Token: def get_token(self) -> FlowToken:
"""Get token""" """Get token"""
pending_user = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] pending_user = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
current_stage: EmailStage = self.executor.current_stage current_stage: EmailStage = self.executor.current_stage
@ -65,10 +64,14 @@ class EmailStageView(ChallengeStageView):
) # + 1 because django timesince always rounds down ) # + 1 because django timesince always rounds down
identifier = slugify(f"ak-email-stage-{current_stage.name}-{pending_user}") identifier = slugify(f"ak-email-stage-{current_stage.name}-{pending_user}")
# Don't check for validity here, we only care if the token exists # Don't check for validity here, we only care if the token exists
tokens = Token.objects.filter(identifier=identifier) tokens = FlowToken.objects.filter(identifier=identifier)
if not tokens.exists(): if not tokens.exists():
return Token.objects.create( return FlowToken.objects.create(
expires=now() + valid_delta, user=pending_user, identifier=identifier expires=now() + valid_delta,
user=pending_user,
identifier=identifier,
flow=self.executor.flow,
_plan=FlowToken.pickle(self.executor.plan),
) )
token = tokens.first() token = tokens.first()
# Check if token is expired and rotate key if so # Check if token is expired and rotate key if so
@ -97,13 +100,9 @@ class EmailStageView(ChallengeStageView):
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
# Check if the user came back from the email link to verify # Check if the user came back from the email link to verify
if QS_KEY_TOKEN in request.session.get(SESSION_KEY_GET, {}): if QS_KEY_TOKEN in request.session.get(
tokens = Token.filter_not_expired(key=request.session[SESSION_KEY_GET][QS_KEY_TOKEN]) SESSION_KEY_GET, {}
if not tokens.exists(): ) and self.executor.plan.context.get(PLAN_CONTEXT_IS_RESTORED, False):
return self.executor.stage_invalid(_("Invalid token"))
token = tokens.first()
self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] = token.user
token.delete()
messages.success(request, _("Successfully verified Email.")) messages.success(request, _("Successfully verified Email."))
if self.executor.current_stage.activate_user_on_success: if self.executor.current_stage.activate_user_on_success:
self.executor.plan.context[PLAN_CONTEXT_PENDING_USER].is_active = True self.executor.plan.context[PLAN_CONTEXT_PENDING_USER].is_active = True

View file

@ -18,7 +18,7 @@ from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTyp
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
from authentik.flows.stage import ChallengeStageView from authentik.flows.stage import ChallengeStageView
from authentik.policies.engine import PolicyEngine from authentik.policies.engine import PolicyEngine
from authentik.policies.models import PolicyBinding, PolicyBindingModel from authentik.policies.models import PolicyBinding, PolicyBindingModel, PolicyEngineMode
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
from authentik.stages.prompt.signals import password_validate from authentik.stages.prompt.signals import password_validate
@ -110,6 +110,7 @@ class PromptChallengeResponse(ChallengeResponse):
user = self.plan.context.get(PLAN_CONTEXT_PENDING_USER, get_anonymous_user()) user = self.plan.context.get(PLAN_CONTEXT_PENDING_USER, get_anonymous_user())
engine = ListPolicyEngine(self.stage.validation_policies.all(), user, self.request) engine = ListPolicyEngine(self.stage.validation_policies.all(), user, self.request)
engine.mode = PolicyEngineMode.MODE_ALL
engine.request.context[PLAN_CONTEXT_PROMPT] = attrs engine.request.context[PLAN_CONTEXT_PROMPT] = attrs
engine.request.context.update(attrs) engine.request.context.update(attrs)
engine.build() engine.build()

4
go.mod
View file

@ -29,11 +29,11 @@ require (
github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_golang v1.11.0
github.com/recws-org/recws v1.3.1 github.com/recws-org/recws v1.3.1
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
goauthentik.io/api v0.2021104.7 goauthentik.io/api v0.2021104.10
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b
gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect

4
go.sum
View file

@ -561,8 +561,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
goauthentik.io/api v0.2021104.7 h1:JWKypuvYWWPqq8c8xLN8qVv5ny8TqsfmLdqNwJM9bZk= goauthentik.io/api v0.2021104.10 h1:5A2KLhwe5uSkPPiZDg8td3OLFKxcODSMqkyvRSavcUM=
goauthentik.io/api v0.2021104.7/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE= goauthentik.io/api v0.2021104.10/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

View file

@ -25,6 +25,7 @@ type Request struct {
func NewRequest(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (*Request, *sentry.Span) { func NewRequest(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (*Request, *sentry.Span) {
rid := uuid.New().String() rid := uuid.New().String()
bindDN = strings.ToLower(bindDN) bindDN = strings.ToLower(bindDN)
searchReq.BaseDN = strings.ToLower(searchReq.BaseDN)
span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.search", sentry.TransactionName("authentik.providers.ldap.search")) span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.search", sentry.TransactionName("authentik.providers.ldap.search"))
span.SetTag("request_uid", rid) span.SetTag("request_uid", rid)
span.SetTag("user.username", bindDN) span.SetTag("user.username", bindDN)

View file

@ -13,6 +13,4 @@ type Claims struct {
Name string `json:"name"` Name string `json:"name"`
PreferredUsername string `json:"preferred_username"` PreferredUsername string `json:"preferred_username"`
Groups []string `json:"groups"` Groups []string `json:"groups"`
RawToken string
} }

View file

@ -25,7 +25,6 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) {
headers.Set("X-authentik-email", c.Email) headers.Set("X-authentik-email", c.Email)
headers.Set("X-authentik-name", c.Name) headers.Set("X-authentik-name", c.Name)
headers.Set("X-authentik-uid", c.Sub) headers.Set("X-authentik-uid", c.Sub)
headers.Set("X-authentik-jwt", c.RawToken)
// System headers // System headers
headers.Set("X-authentik-meta-jwks", a.proxyConfig.OidcConfiguration.JwksUri) headers.Set("X-authentik-meta-jwks", a.proxyConfig.OidcConfiguration.JwksUri)

View file

@ -45,6 +45,5 @@ func (a *Application) redeemCallback(r *http.Request, shouldState string) (*Clai
if err := idToken.Claims(&claims); err != nil { if err := idToken.Claims(&claims); err != nil {
return nil, err return nil, err
} }
claims.RawToken = rawIDToken
return claims, nil return claims, nil
} }

View file

@ -1,5 +1,5 @@
# Stage 1: Build # Stage 1: Build
FROM docker.io/golang:1.17.3-bullseye AS builder FROM docker.io/golang:1.17.4-bullseye AS builder
WORKDIR /go/src/goauthentik.io WORKDIR /go/src/goauthentik.io

View file

@ -68,6 +68,9 @@ if [[ "$1" == "server" ]]; then
elif [[ "$1" == "worker" ]]; then elif [[ "$1" == "worker" ]]; then
echo "worker" > $MODE_FILE echo "worker" > $MODE_FILE
check_if_root "celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events" check_if_root "celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events"
elif [[ "$1" == "flower" ]]; then
echo "flower" > $MODE_FILE
celery -A authentik.root.celery flower
elif [[ "$1" == "backup" ]]; then elif [[ "$1" == "backup" ]]; then
wait_for_db wait_for_db
python -m manage dbbackup --clean python -m manage dbbackup --clean
@ -87,6 +90,8 @@ elif [[ "$1" == "healthcheck" ]]; then
curl --user-agent "goauthentik.io lifecycle Healthcheck" -I http://localhost:9000/-/health/ready/ curl --user-agent "goauthentik.io lifecycle Healthcheck" -I http://localhost:9000/-/health/ready/
elif [[ $mode == "worker" ]]; then elif [[ $mode == "worker" ]]; then
celery -A authentik.root.celery inspect ping -d celery@$HOSTNAME --timeout 5 -j celery -A authentik.root.celery inspect ping -d celery@$HOSTNAME --timeout 5 -j
elif [[ $mode == "flower" ]]; then
curl http://localhost:5555/metrics
fi fi
elif [[ "$1" == "dump_config" ]]; then elif [[ "$1" == "dump_config" ]]; then
python -m authentik.lib.config python -m authentik.lib.config

View file

@ -7,7 +7,7 @@ ENV NODE_ENV=production
RUN cd /static && npm i && npm run build-proxy RUN cd /static && npm i && npm run build-proxy
# Stage 2: Build # Stage 2: Build
FROM docker.io/golang:1.17.3-bullseye AS builder FROM docker.io/golang:1.17.4-bullseye AS builder
WORKDIR /go/src/goauthentik.io WORKDIR /go/src/goauthentik.io

View file

@ -5764,6 +5764,14 @@ paths:
name: providers__isnull name: providers__isnull
schema: schema:
type: boolean type: boolean
- in: query
name: providers_by_pk
schema:
type: array
items:
type: integer
explode: true
style: form
- name: search - name: search
required: false required: false
in: query in: query
@ -5952,6 +5960,14 @@ paths:
name: providers__isnull name: providers__isnull
schema: schema:
type: boolean type: boolean
- in: query
name: providers_by_pk
schema:
type: array
items:
type: integer
explode: true
style: form
- name: search - name: search
required: false required: false
in: query in: query
@ -11645,6 +11661,14 @@ paths:
name: download name: download
schema: schema:
type: boolean type: boolean
- in: query
name: force_binding
schema:
type: string
enum:
- urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
- urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect
description: Optionally force the metadata to only include one binding.
- in: path - in: path
name: id name: id
schema: schema:
@ -13562,6 +13586,30 @@ paths:
$ref: '#/components/schemas/ValidationError' $ref: '#/components/schemas/ValidationError'
'403': '403':
$ref: '#/components/schemas/GenericError' $ref: '#/components/schemas/GenericError'
post:
operationId: sources_user_connections_oauth_create
description: Source Viewset
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserOAuthSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/UserOAuthSourceConnection'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/sources/user_connections/oauth/{id}/: /sources/user_connections/oauth/{id}/:
get: get:
operationId: sources_user_connections_oauth_retrieve operationId: sources_user_connections_oauth_retrieve
@ -13746,6 +13794,30 @@ paths:
$ref: '#/components/schemas/ValidationError' $ref: '#/components/schemas/ValidationError'
'403': '403':
$ref: '#/components/schemas/GenericError' $ref: '#/components/schemas/GenericError'
post:
operationId: sources_user_connections_plex_create
description: Plex Source connection Serializer
tags:
- sources
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PlexSourceConnectionRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/PlexSourceConnection'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/sources/user_connections/plex/{id}/: /sources/user_connections/plex/{id}/:
get: get:
operationId: sources_user_connections_plex_retrieve operationId: sources_user_connections_plex_retrieve
@ -28135,6 +28207,10 @@ components:
type: string type: string
minLength: 1 minLength: 1
maxLength: 255 maxLength: 255
access_token:
type: string
writeOnly: true
nullable: true
PatchedUserRequest: PatchedUserRequest:
type: object type: object
description: User Serializer description: User Serializer
@ -30881,6 +30957,10 @@ components:
type: string type: string
minLength: 1 minLength: 1
maxLength: 255 maxLength: 255
access_token:
type: string
writeOnly: true
nullable: true
required: required:
- identifier - identifier
- source - source

View file

@ -16,6 +16,7 @@ from authentik.flows.models import Flow
from authentik.policies.expression.models import ExpressionPolicy from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import PolicyBinding from authentik.policies.models import PolicyBinding
from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping, SAMLProvider from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping, SAMLProvider
from authentik.sources.saml.processors.constants import SAML_BINDING_POST
from tests.e2e.utils import SeleniumTestCase, apply_migration, object_manager, retry from tests.e2e.utils import SeleniumTestCase, apply_migration, object_manager, retry
@ -25,9 +26,18 @@ class TestProviderSAML(SeleniumTestCase):
container: Container container: Container
def setup_client(self, provider: SAMLProvider) -> Container: def setup_client(self, provider: SAMLProvider, force_post: bool = False) -> Container:
"""Setup client saml-sp container which we test SAML against""" """Setup client saml-sp container which we test SAML against"""
client: DockerClient = from_env() client: DockerClient = from_env()
metadata_url = (
self.url(
"authentik_api:samlprovider-metadata",
pk=provider.pk,
)
+ "?download"
)
if force_post:
metadata_url += f"&force_binding={SAML_BINDING_POST}"
container = client.containers.run( container = client.containers.run(
image="beryju.org/saml-test-sp:latest", image="beryju.org/saml-test-sp:latest",
detach=True, detach=True,
@ -41,13 +51,7 @@ class TestProviderSAML(SeleniumTestCase):
environment={ environment={
"SP_ENTITY_ID": provider.issuer, "SP_ENTITY_ID": provider.issuer,
"SP_SSO_BINDING": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", "SP_SSO_BINDING": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
"SP_METADATA_URL": ( "SP_METADATA_URL": metadata_url,
self.url(
"authentik_api:samlprovider-metadata",
pk=provider.pk,
)
+ "?download"
),
}, },
) )
while True: while True:
@ -197,6 +201,83 @@ class TestProviderSAML(SeleniumTestCase):
[self.user.email], [self.user.email],
) )
@retry()
@apply_migration("authentik_flows", "0008_default_flows")
@apply_migration("authentik_flows", "0011_flow_title")
@apply_migration("authentik_flows", "0010_provider_flows")
@apply_migration("authentik_crypto", "0002_create_self_signed_kp")
@object_manager
def test_sp_initiated_explicit_post(self):
"""test SAML Provider flow SP-initiated flow (explicit consent) (POST binding)"""
# Bootstrap all needed objects
authorization_flow = Flow.objects.get(
slug="default-provider-authorization-explicit-consent"
)
provider: SAMLProvider = SAMLProvider.objects.create(
name="saml-test",
acs_url="http://localhost:9009/saml/acs",
audience="authentik-e2e",
issuer="authentik-e2e",
sp_binding=SAMLBindings.POST,
authorization_flow=authorization_flow,
signing_kp=create_test_cert(),
)
provider.property_mappings.set(SAMLPropertyMapping.objects.all())
provider.save()
app = Application.objects.create(
name="SAML",
slug="authentik-saml",
provider=provider,
)
self.container = self.setup_client(provider, True)
self.driver.get("http://localhost:9009")
self.login()
self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "ak-flow-executor")))
flow_executor = self.get_shadow_root("ak-flow-executor")
consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor)
self.assertIn(
app.name,
consent_stage.find_element(By.CSS_SELECTOR, "#header-text").text,
)
consent_stage.find_element(
By.CSS_SELECTOR,
("[type=submit]"),
).click()
self.wait_for_url("http://localhost:9009/")
body = loads(self.driver.find_element(By.CSS_SELECTOR, "pre").text)
self.assertEqual(
body["attr"]["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],
[self.user.name],
)
self.assertEqual(
body["attr"][
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"
],
[self.user.username],
)
self.assertEqual(
body["attr"]["http://schemas.goauthentik.io/2021/02/saml/username"],
[self.user.username],
)
self.assertEqual(
body["attr"]["http://schemas.goauthentik.io/2021/02/saml/uid"],
[str(self.user.pk)],
)
self.assertEqual(
body["attr"]["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"],
[self.user.email],
)
self.assertEqual(
body["attr"]["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"],
[self.user.email],
)
@retry() @retry()
@apply_migration("authentik_flows", "0008_default_flows") @apply_migration("authentik_flows", "0008_default_flows")
@apply_migration("authentik_flows", "0011_flow_title") @apply_migration("authentik_flows", "0011_flow_title")

416
web/package-lock.json generated
View file

@ -15,7 +15,7 @@
"@babel/preset-env": "^7.16.4", "@babel/preset-env": "^7.16.4",
"@babel/preset-typescript": "^7.16.0", "@babel/preset-typescript": "^7.16.0",
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@goauthentik/api": "^2021.10.4-1638522576", "@goauthentik/api": "^2021.10.4-1638781871",
"@jackfranklin/rollup-plugin-markdown": "^0.3.0", "@jackfranklin/rollup-plugin-markdown": "^0.3.0",
"@lingui/cli": "^3.13.0", "@lingui/cli": "^3.13.0",
"@lingui/core": "^3.13.0", "@lingui/core": "^3.13.0",
@ -29,23 +29,23 @@
"@rollup/plugin-node-resolve": "^13.0.6", "@rollup/plugin-node-resolve": "^13.0.6",
"@rollup/plugin-replace": "^3.0.0", "@rollup/plugin-replace": "^3.0.0",
"@rollup/plugin-typescript": "^8.3.0", "@rollup/plugin-typescript": "^8.3.0",
"@sentry/browser": "^6.15.0", "@sentry/browser": "^6.16.0",
"@sentry/tracing": "^6.15.0", "@sentry/tracing": "^6.16.0",
"@squoosh/cli": "^0.7.2", "@squoosh/cli": "^0.7.2",
"@trivago/prettier-plugin-sort-imports": "^3.1.1", "@trivago/prettier-plugin-sort-imports": "^3.1.1",
"@types/chart.js": "^2.9.34", "@types/chart.js": "^2.9.34",
"@types/codemirror": "5.60.5", "@types/codemirror": "5.60.5",
"@types/grecaptcha": "^3.0.3", "@types/grecaptcha": "^3.0.3",
"@typescript-eslint/eslint-plugin": "^5.5.0", "@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.5.0", "@typescript-eslint/parser": "^5.6.0",
"@webcomponents/webcomponentsjs": "^2.6.0", "@webcomponents/webcomponentsjs": "^2.6.0",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"chart.js": "^3.6.1", "chart.js": "^3.6.2",
"chartjs-adapter-moment": "^1.0.0", "chartjs-adapter-moment": "^1.0.0",
"codemirror": "^5.64.0", "codemirror": "^5.64.0",
"construct-style-sheets-polyfill": "^2.4.16", "construct-style-sheets-polyfill": "^2.4.16",
"eslint": "^8.3.0", "eslint": "^8.4.1",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-custom-elements": "0.0.4", "eslint-plugin-custom-elements": "0.0.4",
"eslint-plugin-lit": "^1.6.1", "eslint-plugin-lit": "^1.6.1",
@ -53,7 +53,7 @@
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
"lit": "^2.0.2", "lit": "^2.0.2",
"moment": "^2.29.1", "moment": "^2.29.1",
"prettier": "^2.5.0", "prettier": "^2.5.1",
"rapidoc": "^9.1.3", "rapidoc": "^9.1.3",
"rollup": "^2.60.2", "rollup": "^2.60.2",
"rollup-plugin-copy": "^3.4.0", "rollup-plugin-copy": "^3.4.0",
@ -1655,13 +1655,13 @@
} }
}, },
"node_modules/@eslint/eslintrc": { "node_modules/@eslint/eslintrc": {
"version": "1.0.4", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
"integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
"dependencies": { "dependencies": {
"ajv": "^6.12.4", "ajv": "^6.12.4",
"debug": "^4.3.2", "debug": "^4.3.2",
"espree": "^9.0.0", "espree": "^9.2.0",
"globals": "^13.9.0", "globals": "^13.9.0",
"ignore": "^4.0.6", "ignore": "^4.0.6",
"import-fresh": "^3.2.1", "import-fresh": "^3.2.1",
@ -1708,16 +1708,16 @@
} }
}, },
"node_modules/@goauthentik/api": { "node_modules/@goauthentik/api": {
"version": "2021.10.4-1638522576", "version": "2021.10.4-1638781871",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638522576.tgz", "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638781871.tgz",
"integrity": "sha512-ojnhGFPnEHXPeMULMtRUBoRVB8k0B73l3O5UL8NSipaY2ZC7jSscIQKDZWz7yvvx9NPMV34kKJ9NK8N+/jzfgw==" "integrity": "sha512-QI/pqVVCt/W+iXZGXXipAYX39CBpuUEPDxFKPCiQyU+G0+rLYt1T1umBjTIlIEXRKC8xKSInLkDS/GEz32kXNA=="
}, },
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.6.0", "version": "0.9.2",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
"integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
"dependencies": { "dependencies": {
"@humanwhocodes/object-schema": "^1.2.0", "@humanwhocodes/object-schema": "^1.2.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
}, },
@ -1726,9 +1726,9 @@
} }
}, },
"node_modules/@humanwhocodes/object-schema": { "node_modules/@humanwhocodes/object-schema": {
"version": "1.2.0", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==" "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
}, },
"node_modules/@jackfranklin/rollup-plugin-markdown": { "node_modules/@jackfranklin/rollup-plugin-markdown": {
"version": "0.3.0", "version": "0.3.0",
@ -2370,13 +2370,13 @@
} }
}, },
"node_modules/@sentry/browser": { "node_modules/@sentry/browser": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.16.0.tgz",
"integrity": "sha512-ZiqfHK5DMVgDsgMTuSwxilWIqEnZzy4yuJ9Sr6Iap1yZddPSiKHYjbBieSHn57UsWHViRB3ojbwu44LfvXKJdQ==", "integrity": "sha512-rpFrS/DPKH9NAWfEhrgpVmqJtfUIGvl9y6KQv0QsNv7X0ZISNtsoHIUe2jVrbjysjWXrJCryCxcSxNgqsa4Www==",
"dependencies": { "dependencies": {
"@sentry/core": "6.15.0", "@sentry/core": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"engines": { "engines": {
@ -2389,14 +2389,14 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}, },
"node_modules/@sentry/core": { "node_modules/@sentry/core": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.16.0.tgz",
"integrity": "sha512-mCbKyqvD1G3Re6gv6N8tRkBz84gvVWDfLtC6d1WBArIopzter6ktEbvq0cMT6EOvGI2OLXuJ6mtHA93/Q0gGpw==", "integrity": "sha512-XqIlMjefuJmwQSAzv9J1PtV6+sXiz1dgBbtRr6e+QGIYZ+BDkuyDQv/HsGPfxxMHxgJBxBzi71FFLjEJsF6CBg==",
"dependencies": { "dependencies": {
"@sentry/hub": "6.15.0", "@sentry/hub": "6.16.0",
"@sentry/minimal": "6.15.0", "@sentry/minimal": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"engines": { "engines": {
@ -2409,12 +2409,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}, },
"node_modules/@sentry/hub": { "node_modules/@sentry/hub": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.16.0.tgz",
"integrity": "sha512-cUbHPeG6kKpGBaEMgbTWeU03Y1Up5T3urGF+cgtrn80PmPYYSUPvVvWlZQWPb8CJZ1yQ0gySWo5RUTatBFrEHA==", "integrity": "sha512-NBkcgGjnYsoXyIJwi2TGCxGnxbDJc/t++0ukFoBRy6RL/pw2YnryCu8PWNFsDkZdlb1zt5SIC6Kui+q1ViNS/A==",
"dependencies": { "dependencies": {
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"engines": { "engines": {
@ -2427,12 +2427,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}, },
"node_modules/@sentry/minimal": { "node_modules/@sentry/minimal": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.16.0.tgz",
"integrity": "sha512-7RJIvZsjBa1qFUfMrAzQsWdfZT6Gm4t6ZTYfkpsXPBA35hkzglKbBrhhsUvkxGIhUGw/PiCUqxBUjcmzQP0vfg==", "integrity": "sha512-9/h0J9BDDY5W/dKILGEq3ewECspNoxcXuly/WOWQdt2SQpIcoh8l/dF8iTXle+icndin0EiMEyHOzaCPWG24oQ==",
"dependencies": { "dependencies": {
"@sentry/hub": "6.15.0", "@sentry/hub": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"engines": { "engines": {
@ -2445,14 +2445,14 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}, },
"node_modules/@sentry/tracing": { "node_modules/@sentry/tracing": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.16.0.tgz",
"integrity": "sha512-V5unvX8qNEfdawX+m2n0jKgmH/YR2ItWZLH+3UevBTptO+xyfvRtpgGXYWUCo3iGvFgWb1C+iIC7LViR9rTvBg==", "integrity": "sha512-vTTjGnLc9fa3jM0RKkEgOLW23CiPb1Kh6bkHbUw68d3DVz6o0Tj2SqzW+Y+LaIwlFjhrozf+YV/KS9vj4BhHTw==",
"dependencies": { "dependencies": {
"@sentry/hub": "6.15.0", "@sentry/hub": "6.16.0",
"@sentry/minimal": "6.15.0", "@sentry/minimal": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"engines": { "engines": {
@ -2465,19 +2465,19 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}, },
"node_modules/@sentry/types": { "node_modules/@sentry/types": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.16.0.tgz",
"integrity": "sha512-zBw5gPUsofXUSpS3ZAXqRNedLRBvirl3sqkj2Lez7X2EkKRgn5D8m9fQIrig/X3TsKcXUpijDW5Buk5zeCVzJA==", "integrity": "sha512-ZgIyLYlQS4SPi+d68XD8n9FzoObrNQLWxBuMYMnG3uJSuFeYAJrVYkDRtW4OW0D3awuajYGiHJZC2O5qTRGflA==",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@sentry/utils": { "node_modules/@sentry/utils": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.16.0.tgz",
"integrity": "sha512-gnhKKyFtnNmKWjDizo7VKD0/Vx8cgW1lCusM6WI7jy2jlO3bQA0+Dzgmr4mIReZ74mq4VpOd2Vfrx7ZldW1DMw==", "integrity": "sha512-FJl1AyUVAIzxfEXufWsgX7KxIvOrQawxhAhLXO4vU5xrFrJOteicxAIFJO+GG0QDELgr9siP0Qgeb8LoINWcrw==",
"dependencies": { "dependencies": {
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"engines": { "engines": {
@ -2781,12 +2781,12 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz",
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==", "integrity": "sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==",
"dependencies": { "dependencies": {
"@typescript-eslint/experimental-utils": "5.5.0", "@typescript-eslint/experimental-utils": "5.6.0",
"@typescript-eslint/scope-manager": "5.5.0", "@typescript-eslint/scope-manager": "5.6.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8", "ignore": "^5.1.8",
@ -2834,14 +2834,14 @@
} }
}, },
"node_modules/@typescript-eslint/experimental-utils": { "node_modules/@typescript-eslint/experimental-utils": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz",
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==", "integrity": "sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==",
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.5.0", "@typescript-eslint/scope-manager": "5.6.0",
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/typescript-estree": "5.5.0", "@typescript-eslint/typescript-estree": "5.6.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
}, },
@ -2857,13 +2857,13 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.6.0.tgz",
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==", "integrity": "sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.5.0", "@typescript-eslint/scope-manager": "5.6.0",
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/typescript-estree": "5.5.0", "@typescript-eslint/typescript-estree": "5.6.0",
"debug": "^4.3.2" "debug": "^4.3.2"
}, },
"engines": { "engines": {
@ -2883,12 +2883,12 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz",
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==", "integrity": "sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/visitor-keys": "5.5.0" "@typescript-eslint/visitor-keys": "5.6.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -2899,9 +2899,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.6.0.tgz",
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==", "integrity": "sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA==",
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}, },
@ -2911,12 +2911,12 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz",
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==", "integrity": "sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/visitor-keys": "5.5.0", "@typescript-eslint/visitor-keys": "5.6.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"globby": "^11.0.4", "globby": "^11.0.4",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -2951,11 +2951,11 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz",
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==", "integrity": "sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"eslint-visitor-keys": "^3.0.0" "eslint-visitor-keys": "^3.0.0"
}, },
"engines": { "engines": {
@ -3482,9 +3482,9 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
}, },
"node_modules/chart.js": { "node_modules/chart.js": {
"version": "3.6.1", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.1.tgz", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.2.tgz",
"integrity": "sha512-AycnixR0I325Fp3bqQ7wRJbkIJPwz/9IZtUBvdBWMjK5+nKCy6FZ3VejkDTtB9udePEXNt1UYoGTsNL49JoIbg==" "integrity": "sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg=="
}, },
"node_modules/chartjs-adapter-moment": { "node_modules/chartjs-adapter-moment": {
"version": "1.0.0", "version": "1.0.0",
@ -4035,12 +4035,12 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.3.0", "version": "8.4.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz",
"integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==", "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==",
"dependencies": { "dependencies": {
"@eslint/eslintrc": "^1.0.4", "@eslint/eslintrc": "^1.0.5",
"@humanwhocodes/config-array": "^0.6.0", "@humanwhocodes/config-array": "^0.9.2",
"ajv": "^6.10.0", "ajv": "^6.10.0",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"cross-spawn": "^7.0.2", "cross-spawn": "^7.0.2",
@ -4051,7 +4051,7 @@
"eslint-scope": "^7.1.0", "eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.1.0", "eslint-visitor-keys": "^3.1.0",
"espree": "^9.1.0", "espree": "^9.2.0",
"esquery": "^1.4.0", "esquery": "^1.4.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
@ -4314,9 +4314,9 @@
} }
}, },
"node_modules/espree": { "node_modules/espree": {
"version": "9.1.0", "version": "9.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz",
"integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==", "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==",
"dependencies": { "dependencies": {
"acorn": "^8.6.0", "acorn": "^8.6.0",
"acorn-jsx": "^5.3.1", "acorn-jsx": "^5.3.1",
@ -6767,9 +6767,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "2.5.0", "version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==", "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
@ -9859,13 +9859,13 @@
} }
}, },
"@eslint/eslintrc": { "@eslint/eslintrc": {
"version": "1.0.4", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
"integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
"requires": { "requires": {
"ajv": "^6.12.4", "ajv": "^6.12.4",
"debug": "^4.3.2", "debug": "^4.3.2",
"espree": "^9.0.0", "espree": "^9.2.0",
"globals": "^13.9.0", "globals": "^13.9.0",
"ignore": "^4.0.6", "ignore": "^4.0.6",
"import-fresh": "^3.2.1", "import-fresh": "^3.2.1",
@ -9895,24 +9895,24 @@
"integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="
}, },
"@goauthentik/api": { "@goauthentik/api": {
"version": "2021.10.4-1638522576", "version": "2021.10.4-1638781871",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638522576.tgz", "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638781871.tgz",
"integrity": "sha512-ojnhGFPnEHXPeMULMtRUBoRVB8k0B73l3O5UL8NSipaY2ZC7jSscIQKDZWz7yvvx9NPMV34kKJ9NK8N+/jzfgw==" "integrity": "sha512-QI/pqVVCt/W+iXZGXXipAYX39CBpuUEPDxFKPCiQyU+G0+rLYt1T1umBjTIlIEXRKC8xKSInLkDS/GEz32kXNA=="
}, },
"@humanwhocodes/config-array": { "@humanwhocodes/config-array": {
"version": "0.6.0", "version": "0.9.2",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
"integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
"requires": { "requires": {
"@humanwhocodes/object-schema": "^1.2.0", "@humanwhocodes/object-schema": "^1.2.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
} }
}, },
"@humanwhocodes/object-schema": { "@humanwhocodes/object-schema": {
"version": "1.2.0", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==" "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
}, },
"@jackfranklin/rollup-plugin-markdown": { "@jackfranklin/rollup-plugin-markdown": {
"version": "0.3.0", "version": "0.3.0",
@ -10415,13 +10415,13 @@
} }
}, },
"@sentry/browser": { "@sentry/browser": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.16.0.tgz",
"integrity": "sha512-ZiqfHK5DMVgDsgMTuSwxilWIqEnZzy4yuJ9Sr6Iap1yZddPSiKHYjbBieSHn57UsWHViRB3ojbwu44LfvXKJdQ==", "integrity": "sha512-rpFrS/DPKH9NAWfEhrgpVmqJtfUIGvl9y6KQv0QsNv7X0ZISNtsoHIUe2jVrbjysjWXrJCryCxcSxNgqsa4Www==",
"requires": { "requires": {
"@sentry/core": "6.15.0", "@sentry/core": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -10433,14 +10433,14 @@
} }
}, },
"@sentry/core": { "@sentry/core": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.16.0.tgz",
"integrity": "sha512-mCbKyqvD1G3Re6gv6N8tRkBz84gvVWDfLtC6d1WBArIopzter6ktEbvq0cMT6EOvGI2OLXuJ6mtHA93/Q0gGpw==", "integrity": "sha512-XqIlMjefuJmwQSAzv9J1PtV6+sXiz1dgBbtRr6e+QGIYZ+BDkuyDQv/HsGPfxxMHxgJBxBzi71FFLjEJsF6CBg==",
"requires": { "requires": {
"@sentry/hub": "6.15.0", "@sentry/hub": "6.16.0",
"@sentry/minimal": "6.15.0", "@sentry/minimal": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -10452,12 +10452,12 @@
} }
}, },
"@sentry/hub": { "@sentry/hub": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.16.0.tgz",
"integrity": "sha512-cUbHPeG6kKpGBaEMgbTWeU03Y1Up5T3urGF+cgtrn80PmPYYSUPvVvWlZQWPb8CJZ1yQ0gySWo5RUTatBFrEHA==", "integrity": "sha512-NBkcgGjnYsoXyIJwi2TGCxGnxbDJc/t++0ukFoBRy6RL/pw2YnryCu8PWNFsDkZdlb1zt5SIC6Kui+q1ViNS/A==",
"requires": { "requires": {
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -10469,12 +10469,12 @@
} }
}, },
"@sentry/minimal": { "@sentry/minimal": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.16.0.tgz",
"integrity": "sha512-7RJIvZsjBa1qFUfMrAzQsWdfZT6Gm4t6ZTYfkpsXPBA35hkzglKbBrhhsUvkxGIhUGw/PiCUqxBUjcmzQP0vfg==", "integrity": "sha512-9/h0J9BDDY5W/dKILGEq3ewECspNoxcXuly/WOWQdt2SQpIcoh8l/dF8iTXle+icndin0EiMEyHOzaCPWG24oQ==",
"requires": { "requires": {
"@sentry/hub": "6.15.0", "@sentry/hub": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -10486,14 +10486,14 @@
} }
}, },
"@sentry/tracing": { "@sentry/tracing": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.16.0.tgz",
"integrity": "sha512-V5unvX8qNEfdawX+m2n0jKgmH/YR2ItWZLH+3UevBTptO+xyfvRtpgGXYWUCo3iGvFgWb1C+iIC7LViR9rTvBg==", "integrity": "sha512-vTTjGnLc9fa3jM0RKkEgOLW23CiPb1Kh6bkHbUw68d3DVz6o0Tj2SqzW+Y+LaIwlFjhrozf+YV/KS9vj4BhHTw==",
"requires": { "requires": {
"@sentry/hub": "6.15.0", "@sentry/hub": "6.16.0",
"@sentry/minimal": "6.15.0", "@sentry/minimal": "6.16.0",
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"@sentry/utils": "6.15.0", "@sentry/utils": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -10505,16 +10505,16 @@
} }
}, },
"@sentry/types": { "@sentry/types": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.16.0.tgz",
"integrity": "sha512-zBw5gPUsofXUSpS3ZAXqRNedLRBvirl3sqkj2Lez7X2EkKRgn5D8m9fQIrig/X3TsKcXUpijDW5Buk5zeCVzJA==" "integrity": "sha512-ZgIyLYlQS4SPi+d68XD8n9FzoObrNQLWxBuMYMnG3uJSuFeYAJrVYkDRtW4OW0D3awuajYGiHJZC2O5qTRGflA=="
}, },
"@sentry/utils": { "@sentry/utils": {
"version": "6.15.0", "version": "6.16.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.15.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.16.0.tgz",
"integrity": "sha512-gnhKKyFtnNmKWjDizo7VKD0/Vx8cgW1lCusM6WI7jy2jlO3bQA0+Dzgmr4mIReZ74mq4VpOd2Vfrx7ZldW1DMw==", "integrity": "sha512-FJl1AyUVAIzxfEXufWsgX7KxIvOrQawxhAhLXO4vU5xrFrJOteicxAIFJO+GG0QDELgr9siP0Qgeb8LoINWcrw==",
"requires": { "requires": {
"@sentry/types": "6.15.0", "@sentry/types": "6.16.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -10790,12 +10790,12 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz",
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==", "integrity": "sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==",
"requires": { "requires": {
"@typescript-eslint/experimental-utils": "5.5.0", "@typescript-eslint/experimental-utils": "5.6.0",
"@typescript-eslint/scope-manager": "5.5.0", "@typescript-eslint/scope-manager": "5.6.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8", "ignore": "^5.1.8",
@ -10820,50 +10820,50 @@
} }
}, },
"@typescript-eslint/experimental-utils": { "@typescript-eslint/experimental-utils": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz",
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==", "integrity": "sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==",
"requires": { "requires": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.5.0", "@typescript-eslint/scope-manager": "5.6.0",
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/typescript-estree": "5.5.0", "@typescript-eslint/typescript-estree": "5.6.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.6.0.tgz",
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==", "integrity": "sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==",
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.5.0", "@typescript-eslint/scope-manager": "5.6.0",
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/typescript-estree": "5.5.0", "@typescript-eslint/typescript-estree": "5.6.0",
"debug": "^4.3.2" "debug": "^4.3.2"
} }
}, },
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz",
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==", "integrity": "sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==",
"requires": { "requires": {
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/visitor-keys": "5.5.0" "@typescript-eslint/visitor-keys": "5.6.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.6.0.tgz",
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==" "integrity": "sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA=="
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz",
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==", "integrity": "sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==",
"requires": { "requires": {
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"@typescript-eslint/visitor-keys": "5.5.0", "@typescript-eslint/visitor-keys": "5.6.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"globby": "^11.0.4", "globby": "^11.0.4",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -10882,11 +10882,11 @@
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.5.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz",
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==", "integrity": "sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==",
"requires": { "requires": {
"@typescript-eslint/types": "5.5.0", "@typescript-eslint/types": "5.6.0",
"eslint-visitor-keys": "^3.0.0" "eslint-visitor-keys": "^3.0.0"
}, },
"dependencies": { "dependencies": {
@ -11246,9 +11246,9 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
}, },
"chart.js": { "chart.js": {
"version": "3.6.1", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.1.tgz", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.2.tgz",
"integrity": "sha512-AycnixR0I325Fp3bqQ7wRJbkIJPwz/9IZtUBvdBWMjK5+nKCy6FZ3VejkDTtB9udePEXNt1UYoGTsNL49JoIbg==" "integrity": "sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg=="
}, },
"chartjs-adapter-moment": { "chartjs-adapter-moment": {
"version": "1.0.0", "version": "1.0.0",
@ -11666,12 +11666,12 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
}, },
"eslint": { "eslint": {
"version": "8.3.0", "version": "8.4.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz",
"integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==", "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==",
"requires": { "requires": {
"@eslint/eslintrc": "^1.0.4", "@eslint/eslintrc": "^1.0.5",
"@humanwhocodes/config-array": "^0.6.0", "@humanwhocodes/config-array": "^0.9.2",
"ajv": "^6.10.0", "ajv": "^6.10.0",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"cross-spawn": "^7.0.2", "cross-spawn": "^7.0.2",
@ -11682,7 +11682,7 @@
"eslint-scope": "^7.1.0", "eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.1.0", "eslint-visitor-keys": "^3.1.0",
"espree": "^9.1.0", "espree": "^9.2.0",
"esquery": "^1.4.0", "esquery": "^1.4.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
@ -11853,9 +11853,9 @@
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
}, },
"espree": { "espree": {
"version": "9.1.0", "version": "9.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz",
"integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==", "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==",
"requires": { "requires": {
"acorn": "^8.6.0", "acorn": "^8.6.0",
"acorn-jsx": "^5.3.1", "acorn-jsx": "^5.3.1",
@ -13714,9 +13714,9 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
}, },
"prettier": { "prettier": {
"version": "2.5.0", "version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==" "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg=="
}, },
"pretty-format": { "pretty-format": {
"version": "26.6.2", "version": "26.6.2",

View file

@ -51,7 +51,7 @@
"@babel/preset-env": "^7.16.4", "@babel/preset-env": "^7.16.4",
"@babel/preset-typescript": "^7.16.0", "@babel/preset-typescript": "^7.16.0",
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@goauthentik/api": "^2021.10.4-1638522576", "@goauthentik/api": "^2021.10.4-1638781871",
"@jackfranklin/rollup-plugin-markdown": "^0.3.0", "@jackfranklin/rollup-plugin-markdown": "^0.3.0",
"@lingui/cli": "^3.13.0", "@lingui/cli": "^3.13.0",
"@lingui/core": "^3.13.0", "@lingui/core": "^3.13.0",
@ -65,23 +65,23 @@
"@rollup/plugin-node-resolve": "^13.0.6", "@rollup/plugin-node-resolve": "^13.0.6",
"@rollup/plugin-replace": "^3.0.0", "@rollup/plugin-replace": "^3.0.0",
"@rollup/plugin-typescript": "^8.3.0", "@rollup/plugin-typescript": "^8.3.0",
"@sentry/browser": "^6.15.0", "@sentry/browser": "^6.16.0",
"@sentry/tracing": "^6.15.0", "@sentry/tracing": "^6.16.0",
"@squoosh/cli": "^0.7.2", "@squoosh/cli": "^0.7.2",
"@trivago/prettier-plugin-sort-imports": "^3.1.1", "@trivago/prettier-plugin-sort-imports": "^3.1.1",
"@types/chart.js": "^2.9.34", "@types/chart.js": "^2.9.34",
"@types/codemirror": "5.60.5", "@types/codemirror": "5.60.5",
"@types/grecaptcha": "^3.0.3", "@types/grecaptcha": "^3.0.3",
"@typescript-eslint/eslint-plugin": "^5.5.0", "@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.5.0", "@typescript-eslint/parser": "^5.6.0",
"@webcomponents/webcomponentsjs": "^2.6.0", "@webcomponents/webcomponentsjs": "^2.6.0",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"chart.js": "^3.6.1", "chart.js": "^3.6.2",
"chartjs-adapter-moment": "^1.0.0", "chartjs-adapter-moment": "^1.0.0",
"codemirror": "^5.64.0", "codemirror": "^5.64.0",
"construct-style-sheets-polyfill": "^2.4.16", "construct-style-sheets-polyfill": "^2.4.16",
"eslint": "^8.3.0", "eslint": "^8.4.1",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-custom-elements": "0.0.4", "eslint-plugin-custom-elements": "0.0.4",
"eslint-plugin-lit": "^1.6.1", "eslint-plugin-lit": "^1.6.1",
@ -89,7 +89,7 @@
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
"lit": "^2.0.2", "lit": "^2.0.2",
"moment": "^2.29.1", "moment": "^2.29.1",
"prettier": "^2.5.0", "prettier": "^2.5.1",
"rapidoc": "^9.1.3", "rapidoc": "^9.1.3",
"rollup": "^2.60.2", "rollup": "^2.60.2",
"rollup-plugin-copy": "^3.4.0", "rollup-plugin-copy": "^3.4.0",

View file

@ -83,9 +83,6 @@ html > form > input {
color: var(--pf-global--danger-color--100); color: var(--pf-global--danger-color--100);
} }
.ak-static-page h1 {
color: var(--ak-dark-foreground);
}
.form-help-text { .form-help-text {
color: var(--pf-global--Color--100); color: var(--pf-global--Color--100);
} }
@ -96,6 +93,9 @@ html > form > input {
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
.ak-static-page h1 {
color: var(--ak-dark-foreground);
}
body { body {
background-color: var(--ak-dark-background) !important; background-color: var(--ak-dark-background) !important;
} }

View file

@ -1,17 +1,32 @@
import { LitElement, TemplateResult, html } from "lit"; import { LitElement, TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { EVENT_REFRESH } from "../../constants";
@customElement("ak-dropdown") @customElement("ak-dropdown")
export class DropdownButton extends LitElement { export class DropdownButton extends LitElement {
menu: HTMLElement | null;
constructor() { constructor() {
super(); super();
const menu = this.querySelector<HTMLElement>(".pf-c-dropdown__menu"); this.menu = this.querySelector<HTMLElement>(".pf-c-dropdown__menu");
this.querySelectorAll("button.pf-c-dropdown__toggle").forEach((btn) => { this.querySelectorAll("button.pf-c-dropdown__toggle").forEach((btn) => {
btn.addEventListener("click", () => { btn.addEventListener("click", () => {
if (!menu) return; if (!this.menu) return;
menu.hidden = !menu.hidden; this.menu.hidden = !this.menu.hidden;
}); });
}); });
window.addEventListener(EVENT_REFRESH, this.clickHandler);
}
clickHandler = (): void => {
if (!this.menu) return;
this.menu.hidden = true;
};
disconnectedCallback(): void {
super.disconnectedCallback();
window.removeEventListener(EVENT_REFRESH, this.clickHandler);
} }
render(): TemplateResult { render(): TemplateResult {

View file

@ -95,7 +95,7 @@ export class NotificationDrawer extends LitElement {
class="pf-c-dropdown__toggle pf-m-plain" class="pf-c-dropdown__toggle pf-m-plain"
href="#/events/log/${item.event?.pk}" href="#/events/log/${item.event?.pk}"
> >
<i class="fas fas fa-share-square"></i> <i class="fas fa-share-square"></i>
</a> </a>
`} `}
<button <button

View file

@ -143,7 +143,7 @@ export class IdentificationStage extends BaseStage<
} }
renderSource(source: LoginSource): TemplateResult { renderSource(source: LoginSource): TemplateResult {
let icon = html`<i class="fas fas fa-share-square" title="${source.name}"></i>`; let icon = html`<i class="fas fa-share-square" title="${source.name}"></i>`;
if (source.iconUrl) { if (source.iconUrl) {
icon = html`<img src="${source.iconUrl}" alt="${source.name}" />`; icon = html`<img src="${source.iconUrl}" alt="${source.name}" />`;
} }

View file

@ -1580,6 +1580,10 @@ msgstr "Edit Stage"
msgid "Edit User" msgid "Edit User"
msgstr "Edit User" msgstr "Edit User"
#: src/pages/applications/ApplicationForm.ts
msgid "Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon \"fa-test\"."
msgstr "Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon \"fa-test\"."
#: src/user/LibraryPage.ts #: src/user/LibraryPage.ts
msgid "Either no applications are defined, or you don't have access to any." msgid "Either no applications are defined, or you don't have access to any."
msgstr "Either no applications are defined, or you don't have access to any." msgstr "Either no applications are defined, or you don't have access to any."
@ -5619,6 +5623,10 @@ msgstr "Wait (min)"
msgid "Warning" msgid "Warning"
msgstr "Warning" msgstr "Warning"
#: src/pages/applications/ApplicationViewPage.ts
msgid "Warning: Application is not used by any Outpost."
msgstr "Warning: Application is not used by any Outpost."
#: src/pages/stages/invitation/InvitationListPage.ts #: src/pages/stages/invitation/InvitationListPage.ts
msgid "Warning: No invitation stage is bound to any flow. Invitations will not work as expected." msgid "Warning: No invitation stage is bound to any flow. Invitations will not work as expected."
msgstr "Warning: No invitation stage is bound to any flow. Invitations will not work as expected." msgstr "Warning: No invitation stage is bound to any flow. Invitations will not work as expected."

View file

@ -1568,6 +1568,10 @@ msgstr "Éditer l'étap"
msgid "Edit User" msgid "Edit User"
msgstr "Éditer l'utilisateur" msgstr "Éditer l'utilisateur"
#: src/pages/applications/ApplicationForm.ts
msgid "Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon \"fa-test\"."
msgstr ""
#: src/user/LibraryPage.ts #: src/user/LibraryPage.ts
msgid "Either no applications are defined, or you don't have access to any." msgid "Either no applications are defined, or you don't have access to any."
msgstr "Soit aucune application n'est définie, soit vous n'en avez accès à aucune." msgstr "Soit aucune application n'est définie, soit vous n'en avez accès à aucune."
@ -5557,6 +5561,10 @@ msgstr "Attente (min)"
msgid "Warning" msgid "Warning"
msgstr "Avertissement" msgstr "Avertissement"
#: src/pages/applications/ApplicationViewPage.ts
msgid "Warning: Application is not used by any Outpost."
msgstr ""
#: src/pages/stages/invitation/InvitationListPage.ts #: src/pages/stages/invitation/InvitationListPage.ts
msgid "Warning: No invitation stage is bound to any flow. Invitations will not work as expected." msgid "Warning: No invitation stage is bound to any flow. Invitations will not work as expected."
msgstr "" msgstr ""

View file

@ -1572,6 +1572,10 @@ msgstr ""
msgid "Edit User" msgid "Edit User"
msgstr "" msgstr ""
#: src/pages/applications/ApplicationForm.ts
msgid "Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon \"fa-test\"."
msgstr ""
#: src/user/LibraryPage.ts #: src/user/LibraryPage.ts
msgid "Either no applications are defined, or you don't have access to any." msgid "Either no applications are defined, or you don't have access to any."
msgstr "" msgstr ""
@ -5599,6 +5603,10 @@ msgstr ""
msgid "Warning" msgid "Warning"
msgstr "" msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
msgid "Warning: Application is not used by any Outpost."
msgstr ""
#: src/pages/stages/invitation/InvitationListPage.ts #: src/pages/stages/invitation/InvitationListPage.ts
msgid "Warning: No invitation stage is bound to any flow. Invitations will not work as expected." msgid "Warning: No invitation stage is bound to any flow. Invitations will not work as expected."
msgstr "" msgstr ""

View file

@ -266,6 +266,9 @@ export class ApplicationForm extends ModelForm<Application, string> {
value="${first(this.instance?.metaIcon, "")}" value="${first(this.instance?.metaIcon, "")}"
class="pf-c-form-control" class="pf-c-form-control"
/> />
<p class="pf-c-form__helper-text">
${t`Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".`}
</p>
</ak-form-element-horizontal>`; </ak-form-element-horizontal>`;
}), }),
)} )}

View file

@ -125,7 +125,7 @@ export class ApplicationListPage extends TablePage<Application> {
</ak-forms-modal> </ak-forms-modal>
${item.launchUrl ${item.launchUrl
? html`<a href=${item.launchUrl} target="_blank" class="pf-c-button pf-m-plain"> ? html`<a href=${item.launchUrl} target="_blank" class="pf-c-button pf-m-plain">
<i class="fas fas fa-share-square"></i> <i class="fas fa-share-square"></i>
</a>` </a>`
: html``}`, : html``}`,
]; ];

View file

@ -1,10 +1,11 @@
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { CSSResult, LitElement, TemplateResult, html } from "lit"; import { CSSResult, LitElement, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import AKGlobal from "../../authentik.css"; import AKGlobal from "../../authentik.css";
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFCard from "@patternfly/patternfly/components/Card/card.css"; import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css";
@ -13,7 +14,7 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { Application, CoreApi } from "@goauthentik/api"; import { Application, CoreApi, OutpostsApi } from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../api/Config"; import { DEFAULT_CONFIG } from "../../api/Config";
import "../../elements/EmptyState"; import "../../elements/EmptyState";
@ -36,14 +37,45 @@ export class ApplicationViewPage extends LitElement {
}) })
.then((app) => { .then((app) => {
this.application = app; this.application = app;
if (
app.providerObj &&
[
"authentik_providers_proxy.proxyprovider",
"authentik_providers_ldap.ldapprovider",
].includes(app.providerObj.metaModelName)
) {
new OutpostsApi(DEFAULT_CONFIG)
.outpostsInstancesList({
providersByPk: [app.provider || 0],
pageSize: 1,
})
.then((outposts) => {
if (outposts.pagination.count < 1) {
this.missingOutpost = true;
}
});
}
}); });
} }
@property({ attribute: false }) @property({ attribute: false })
application!: Application; application!: Application;
@state()
missingOutpost = false;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [PFBase, PFPage, PFContent, PFButton, PFDescriptionList, PFGrid, PFCard, AKGlobal]; return [
PFBase,
PFBanner,
PFPage,
PFContent,
PFButton,
PFDescriptionList,
PFGrid,
PFCard,
AKGlobal,
];
} }
render(): TemplateResult { render(): TemplateResult {
@ -62,6 +94,11 @@ export class ApplicationViewPage extends LitElement {
return html`<ak-empty-state ?loading="${true}" header=${t`Loading`}> </ak-empty-state>`; return html`<ak-empty-state ?loading="${true}" header=${t`Loading`}> </ak-empty-state>`;
} }
return html`<ak-tabs> return html`<ak-tabs>
${this.missingOutpost
? html`<div slot="header" class="pf-c-banner pf-m-warning">
${t`Warning: Application is not used by any Outpost.`}
</div>`
: html``}
<section <section
slot="page-overview" slot="page-overview"
data-tab-title="${t`Overview`}" data-tab-title="${t`Overview`}"
@ -88,6 +125,7 @@ export class ApplicationViewPage extends LitElement {
.providerObj?.pk}" .providerObj?.pk}"
> >
${this.application.providerObj?.name} ${this.application.providerObj?.name}
(${this.application.providerObj?.verboseName})
</a> </a>
</div> </div>
</dd> </dd>

View file

@ -70,7 +70,7 @@ export class EventListPage extends TablePage<Event> {
html`<span>${item.clientIp || t`-`}</span>`, html`<span>${item.clientIp || t`-`}</span>`,
html`<span>${item.tenant?.name || t`-`}</span>`, html`<span>${item.tenant?.name || t`-`}</span>`,
html`<a href="#/events/log/${item.pk}"> html`<a href="#/events/log/${item.pk}">
<i class="fas fas fa-share-square"></i> <i class="fas fa-share-square"></i>
</a>`, </a>`,
]; ];
} }

View file

@ -62,6 +62,21 @@ export class LibraryApplication extends LitElement {
]; ];
} }
renderIcon(): TemplateResult {
if (this.application?.metaIcon) {
if (this.application.metaIcon.startsWith("fa://")) {
const icon = this.application.metaIcon.replaceAll("fa://", "");
return html`<i class="fas ${icon}"></i>`;
}
return html`<img
class="app-icon pf-c-avatar"
src="${ifDefined(this.application.metaIcon)}"
alt="${t`Application Icon`}"
/>`;
}
return html`<i class="fas fa-share-square"></i>`;
}
render(): TemplateResult { render(): TemplateResult {
if (!this.application) { if (!this.application) {
return html`<ak-spinner></ak-spinner>`; return html`<ak-spinner></ak-spinner>`;
@ -73,14 +88,7 @@ export class LibraryApplication extends LitElement {
style="background: ${this.background} !important" style="background: ${this.background} !important"
> >
<div class="pf-c-card__header"> <div class="pf-c-card__header">
${this.application.metaIcon <a href="${ifDefined(this.application.launchUrl ?? "")}"> ${this.renderIcon()} </a>
? html`<a href="${ifDefined(this.application.launchUrl ?? "")}"
><img
class="app-icon pf-c-avatar"
src="${ifDefined(this.application.metaIcon)}"
alt="${t`Application Icon`}"
/></a>`
: html`<i class="fas fas fa-share-square"></i>`}
${until( ${until(
uiConfig().then((config) => { uiConfig().then((config) => {
if (!config.enabledFeatures.applicationEdit) { if (!config.enabledFeatures.applicationEdit) {

View file

@ -60,3 +60,5 @@ return False
This policy expects you to have two password fields with `field_key` set to `password` and `password_repeat`. This policy expects you to have two password fields with `field_key` set to `password` and `password_repeat`.
Afterwards, bind this policy to the prompt stage you want to validate. Afterwards, bind this policy to the prompt stage you want to validate.
Before 2021.12, any policy was required to pass for the result to be considered valid. This has been changed, and now all policies are required to be valid.

View file

@ -25,7 +25,7 @@ ak_message("Access denied")
return False return False
``` ```
### `ak_user_has_authenticator(user: User, device_type: Optional[str] = None)` (2021.9+) ### `ak_user_has_authenticator(user: User, device_type: Optional[str] = None) -> bool` (2021.9+)
Check if a user has any authenticator devices. Only fully validated devices are counted. Check if a user has any authenticator devices. Only fully validated devices are counted.
@ -42,6 +42,23 @@ Example:
return ak_user_has_authenticator(request.user) return ak_user_has_authenticator(request.user)
``` ```
### `ak_call_policy(name: str, **kwargs) -> PolicyResult` (2021.12+)
Call another policy with the name *name*. Current request is passed to policy. Key-word arguments
can be used to modify the request's context.
Example:
```python
result = ak_call_policy("test-policy")
# result is a PolicyResult object, so you can access `.passing` and `.messages`.
return result.passing
result = ak_call_policy("test-policy-2", foo="bar")
# Inside the `test-policy-2` you can then use `request.context["foo"]`
return result.passing
```
import Functions from '../expressions/_functions.md' import Functions from '../expressions/_functions.md'
<Functions /> <Functions />

View file

@ -3,10 +3,14 @@ title: Release 2021.12
slug: "2021.12" slug: "2021.12"
--- ---
## Headline Changes ## Headline changes
This release does not have any headline features, and mostly fixes bugs. This release does not have any headline features, and mostly fixes bugs.
## Breaking changes
- stages/prompt: Before 2021.12, any policy was required to pass for the result to be considered valid. This has been changed, and now all policies are required to be valid.
## Minor changes ## Minor changes
- core: make defaults for _change_email and _change_username configurable - core: make defaults for _change_email and _change_username configurable
@ -39,16 +43,11 @@ This release does not have any headline features, and mostly fixes bugs.
- stages/email: fix missing component in response when retrying email send - stages/email: fix missing component in response when retrying email send
- stages/email: minify email css template - stages/email: minify email css template
- stages/email: prevent error with duplicate token - stages/email: prevent error with duplicate token
- web: add rollup config for proxy outpost
- web: attempt to drop fetch errors
- web: improve dark theme for vertical tabs - web: improve dark theme for vertical tabs
- web: only show applications with http link - web: only show applications with http link
- web: use ak-label for boolean values
- web/admin: allow flow edit on flow view page - web/admin: allow flow edit on flow view page
- web/admin: fix actions column on ip reputation page - web/admin: fix actions column on ip reputation page
- web/admin: fix display of banners on provider pages
- web/admin: fix Forms with file uploads not handling errors correctly - web/admin: fix Forms with file uploads not handling errors correctly
- web/admin: fix typo in events action
- web/admin: make object view pages more consistent - web/admin: make object view pages more consistent
- web/admin: make user clickable for bound policies list - web/admin: make user clickable for bound policies list
- web/admin: redesign provider pages to provide more info - web/admin: redesign provider pages to provide more info
@ -62,6 +61,30 @@ This release does not have any headline features, and mostly fixes bugs.
- web/user: fix filtering for applications based on launchURL - web/user: fix filtering for applications based on launchURL
- web/user: fix height issues on user interface - web/user: fix height issues on user interface
## Fixed in 2021.12.1-rc2
- *: don't use go embed to make using custom files easier
- crypto: add certificate discovery to automatically import certificates from lets encrypt
- crypto: fix default API not having an ordering
- outposts: always trigger outpost reconcile on startup
- outposts/ldap: Rework/improve LDAP search logic. (#1687)
- outposts/proxy: make logging fields more consistent
- outposts/proxy: re-add rs256 support
- providers/proxy: fix defaults for traefik integration
- providers/proxy: use wildcard for traefik headers copy
- providers/saml: fix error when using post bindings and user freshly logged in
- providers/saml: fix IndexError in signature check
- sources/ldap: add optional tls verification certificate
- sources/ldap: allow multiple server URIs for loadbalancing and failover
- sources/ldap: don't cache LDAP Connection, use random server
- sources/ldap: handle typeerror during creation of objects when using wrong keyword params
- sources/plex: fix plex token being included in event log
- stages/prompt: fix error when both default and required are set
- web/admin: add spinner to table refresh button to show progress
- web/admin: don't show disabled http basic as red
- web/admin: fix wrong description for reputation policy
- web/flows: fix linting errors
- web/flows: Revise duo authenticator login prompt text (#1872)
## Upgrading ## Upgrading

View file

@ -21,7 +21,7 @@
"react-toggle": "^4.1.2" "react-toggle": "^4.1.2"
}, },
"devDependencies": { "devDependencies": {
"prettier": "2.5.0" "prettier": "2.5.1"
} }
}, },
"node_modules/@algolia/autocomplete-core": { "node_modules/@algolia/autocomplete-core": {
@ -9437,9 +9437,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "2.5.0", "version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==", "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
@ -19824,9 +19824,9 @@
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
}, },
"prettier": { "prettier": {
"version": "2.5.0", "version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==", "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
"dev": true "dev": true
}, },
"pretty-error": { "pretty-error": {

View file

@ -37,6 +37,6 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"prettier": "2.5.0" "prettier": "2.5.1"
} }
} }