From aab329d083ed8f860e50dfbd751bfb1ebfa7936c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:32:44 +0200 Subject: [PATCH 01/44] chore(deps): update docker/setup-buildx-action action to v3.7.1 (#1993) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build_push_dev.yml | 2 +- .github/workflows/build_push_release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_push_dev.yml b/.github/workflows/build_push_dev.yml index 5266965f0..42cce121f 100644 --- a/.github/workflows/build_push_dev.yml +++ b/.github/workflows/build_push_dev.yml @@ -16,7 +16,7 @@ jobs: uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8026d2bc3645ea78b0d2544766a1225eb5691f89 # v3.7.0 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Login to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 diff --git a/.github/workflows/build_push_release.yml b/.github/workflows/build_push_release.yml index 8d39c6c3d..b85655642 100644 --- a/.github/workflows/build_push_release.yml +++ b/.github/workflows/build_push_release.yml @@ -24,7 +24,7 @@ jobs: uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8026d2bc3645ea78b0d2544766a1225eb5691f89 # v3.7.0 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Login to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 From 0c22c3c89c23736542d2b5631b32c0a729a2b036 Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Fri, 4 Oct 2024 12:18:48 +0100 Subject: [PATCH 02/44] fix: documentation title on start page (#1996) --- .github/workflows/publish_docs.yml | 2 +- docs/index.md | 2 +- docs/usage/import_observations.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index e0dd7c93c..9cb91d961 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -4,7 +4,7 @@ on: push: branches: - main - - chore/deploy-docs + - chore/documentation_title permissions: read-all diff --git a/docs/index.md b/docs/index.md index e872fbead..95fd38854 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,4 @@ --- template: home.html -title: Material for MkDocs +title: SecObserve Documentation --- diff --git a/docs/usage/import_observations.md b/docs/usage/import_observations.md index ff24eef5c..76d256678 100644 --- a/docs/usage/import_observations.md +++ b/docs/usage/import_observations.md @@ -33,13 +33,13 @@ A flowchart visualizes the import algorithm: ```mermaid flowchart TD - read(Read observations for a vulnerability check) --> all_observations{For all observations\nof this vulnerability check} - all_observations -- with observation --> identity{Identical observation\nin the same\nvulnerability check?} + read(Read observations for a vulnerability check) --> all_observations{For all observations of this vulnerability check} + all_observations -- with observation --> identity{Identical observation in the same vulnerability check?} subgraph Create or update identity -- yes --> update(Update existing observation) identity -- no --> create(Create new observation) end - all_observations -- finished ----> resolved(Set status to `Resolved` for all untouched observations of this vulnerability check) + all_observations -- finished ----> resolved(Set status to **Resolved** for all untouched observations of this vulnerability check) ``` From cfd6af500e8a55cd305831d7fb11c58fb01d3c01 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:41:39 +0200 Subject: [PATCH 03/44] chore(deps): update keycloak/keycloak docker tag to v26 (#1995) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- docker-compose-dev-keycloak.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose-dev-keycloak.yml b/docker-compose-dev-keycloak.yml index e05b84c66..451a43cf2 100644 --- a/docker-compose-dev-keycloak.yml +++ b/docker-compose-dev-keycloak.yml @@ -84,7 +84,7 @@ services: - "8025:8025" keycloak: - image: keycloak/keycloak:25.0.6 + image: keycloak/keycloak:26.0.0 environment: - KEYCLOAK_ADMIN=admin - KEYCLOAK_ADMIN_PASSWORD=admin From 2daa3be7d10386b1e09a575faed64f0bdd2651d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 19:54:16 +0100 Subject: [PATCH 04/44] fix(deps): update dependency react-oidc-context to v3.2.0 (#1999) --- frontend/package-lock.json | 10 +++++----- frontend/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e40eda2e5..82ba0e126 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -33,7 +33,7 @@ "react-chartjs-2": "5.2.0", "react-dom": "18.3.1", "react-hook-form": "7.53.0", - "react-oidc-context": "3.1.1", + "react-oidc-context": "3.2.0", "react-router": "6.26.2", "react-router-dom": "6.26.2", "runtime-env-cra": "file:lib/runtime-env-cra", @@ -8315,15 +8315,15 @@ "license": "MIT" }, "node_modules/react-oidc-context": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/react-oidc-context/-/react-oidc-context-3.1.1.tgz", - "integrity": "sha512-pXZYVUVOU+wnLFZVh5HFGiAyAHpy0mm7mZBVp5oNuCln/7yd+Uhb7KfYI2QN+LLQI0kIv6FHIcqeUFjMIsM5gA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-oidc-context/-/react-oidc-context-3.2.0.tgz", + "integrity": "sha512-ZLaCRLWV84Cn9pFdsatmblqxLMv0np69GWVXq9RWGqAjppdOGXNIbIxWMByIio0oSCVUwdeqwYRnJme0tjqd8A==", "license": "MIT", "engines": { "node": ">=18" }, "peerDependencies": { - "oidc-client-ts": "^3.0.0", + "oidc-client-ts": "^3.1.0", "react": ">=16.8.0" } }, diff --git a/frontend/package.json b/frontend/package.json index cd852d7bd..fb0bf53a2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,7 +29,7 @@ "react-chartjs-2": "5.2.0", "react-dom": "18.3.1", "react-hook-form": "7.53.0", - "react-oidc-context": "3.1.1", + "react-oidc-context": "3.2.0", "react-router": "6.26.2", "react-router-dom": "6.26.2", "runtime-env-cra": "file:lib/runtime-env-cra", From 00434160c05fba958d0dfc49c61ef83d561e3397 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 08:05:52 +0100 Subject: [PATCH 05/44] chore(deps): update node.js to v20.18.0 (#2002) --- docker/frontend/dev/Dockerfile | 2 +- docker/frontend/prod/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/frontend/dev/Dockerfile b/docker/frontend/dev/Dockerfile index 15a3dd7c0..f8a1d1cc5 100644 --- a/docker/frontend/dev/Dockerfile +++ b/docker/frontend/dev/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20.17.0-alpine3.19@sha256:20b236009deb4c33bf7e255c32fe1e82da7eb0a10245657e0a6a846851fde521 +FROM node:20.18.0-alpine3.19@sha256:2d8c24d9104bda27e07dced6d7110aa728dd917dde8255d8af3678e532b339d6 WORKDIR /app COPY ./frontend/package*.json /app/. diff --git a/docker/frontend/prod/Dockerfile b/docker/frontend/prod/Dockerfile index 42a9bbd0c..f409b25a1 100644 --- a/docker/frontend/prod/Dockerfile +++ b/docker/frontend/prod/Dockerfile @@ -1,5 +1,5 @@ # build environment -FROM node:20.17.0-alpine3.19@sha256:20b236009deb4c33bf7e255c32fe1e82da7eb0a10245657e0a6a846851fde521 AS build +FROM node:20.18.0-alpine3.19@sha256:2d8c24d9104bda27e07dced6d7110aa728dd917dde8255d8af3678e532b339d6 AS build ARG VERSION=unkown From 6d47e153a1a8e23d05a8b2df511b6dcd659d1f95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 09:17:53 +0200 Subject: [PATCH 06/44] chore(deps): update dependency @eslint/compat to v1.2.0 (#1998) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 16 ++++++++++++---- frontend/package.json | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 82ba0e126..38a557b07 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -40,7 +40,7 @@ "tss-react": "4.9.13" }, "devDependencies": { - "@eslint/compat": "1.1.1", + "@eslint/compat": "1.2.0", "@eslint/eslintrc": "3.1.0", "@eslint/js": "9.11.1", "@microsoft/eslint-formatter-sarif": "3.1.0", @@ -1114,13 +1114,21 @@ } }, "node_modules/@eslint/compat": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.1.tgz", - "integrity": "sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.0.tgz", + "integrity": "sha512-CkPWddN7J9JPrQedEr2X7AjK9y1jaMJtxZ4A/+jTMFA2+n5BWhcKHW/EbJyARqg2zzQfgtWUtVmG3hrG6+nGpg==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/@eslint/config-array": { diff --git a/frontend/package.json b/frontend/package.json index fb0bf53a2..c199fe93e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -49,7 +49,7 @@ "not op_mini all" ], "devDependencies": { - "@eslint/compat": "1.1.1", + "@eslint/compat": "1.2.0", "@eslint/eslintrc": "3.1.0", "@eslint/js": "9.11.1", "@microsoft/eslint-formatter-sarif": "3.1.0", From 8c6db62002a0a08ad1c9dfcc93652b997f775919 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 09:21:41 +0200 Subject: [PATCH 07/44] chore(deps): update eslint monorepo to v9.12.0 (#2001) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 60 ++++++++++++++++++++++++++------------ frontend/package.json | 4 +-- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 38a557b07..e69c17b0a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -42,7 +42,7 @@ "devDependencies": { "@eslint/compat": "1.2.0", "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.12.0", "@microsoft/eslint-formatter-sarif": "3.1.0", "@trivago/prettier-plugin-sort-imports": "4.3.0", "@types/inflection": "1.13.2", @@ -55,7 +55,7 @@ "@typescript-eslint/eslint-plugin": "8.8.0", "@typescript-eslint/parser": "8.8.0", "@vitejs/plugin-react": "4.3.2", - "eslint": "9.11.1", + "eslint": "9.12.0", "eslint-plugin-react": "7.37.1", "eslint-plugin-react-hooks": "rc", "eslint-plugin-security": "3.0.1", @@ -1194,9 +1194,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", - "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", "dev": true, "license": "MIT", "engines": { @@ -1284,6 +1284,30 @@ "react": ">=16.3" } }, + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -1323,9 +1347,9 @@ "license": "BSD-3-Clause" }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5036,9 +5060,9 @@ } }, "node_modules/eslint": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", - "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", + "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", "dev": true, "license": "MIT", "dependencies": { @@ -5047,11 +5071,11 @@ "@eslint/config-array": "^0.18.0", "@eslint/core": "^0.6.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.12.0", "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.3.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -5059,9 +5083,9 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -5071,13 +5095,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { diff --git a/frontend/package.json b/frontend/package.json index c199fe93e..f36af18cc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -51,7 +51,7 @@ "devDependencies": { "@eslint/compat": "1.2.0", "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.12.0", "@microsoft/eslint-formatter-sarif": "3.1.0", "@trivago/prettier-plugin-sort-imports": "4.3.0", "@types/inflection": "1.13.2", @@ -64,7 +64,7 @@ "@typescript-eslint/eslint-plugin": "8.8.0", "@typescript-eslint/parser": "8.8.0", "@vitejs/plugin-react": "4.3.2", - "eslint": "9.11.1", + "eslint": "9.12.0", "eslint-plugin-react": "7.37.1", "eslint-plugin-react-hooks": "rc", "eslint-plugin-security": "3.0.1", From 3df715807660191ff94b4dcbcb75881c599c44e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 09:25:36 +0200 Subject: [PATCH 08/44] chore(deps): update actions/cache action to v4.1.0 (#2000) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 9cb91d961..63a3c90a4 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: 3.x - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 with: key: ${{ github.ref }} path: .cache From 597d35870c717aabea8be202af38d21dd8270b1f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 08:35:03 +0100 Subject: [PATCH 09/44] fix(deps): update dependency pre-commit to v4 (#2003) --- backend/poetry.lock | 8 ++++---- backend/pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 83a37dc9c..fe0de7523 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1628,13 +1628,13 @@ type = ["mypy (>=1.11.2)"] [[package]] name = "pre-commit" -version = "3.8.0" +version = "4.0.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = true python-versions = ">=3.9" files = [ - {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, - {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, + {file = "pre_commit-4.0.0-py2.py3-none-any.whl", hash = "sha256:0ca2341cf94ac1865350970951e54b1a50521e57b7b500403307aed4315a1234"}, + {file = "pre_commit-4.0.0.tar.gz", hash = "sha256:5d9807162cc5537940f94f266cbe2d716a75cfad0d78a317a92cac16287cfed6"}, ] [package.dependencies] @@ -2499,4 +2499,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "1201736eed488067efeee9deef12f86e40fa46b9ff1cb9e3f5d446c854475f8c" +content-hash = "651e4f58b7567381fda994d2f62d81f5b4877ba5a2857931ebdc2849ac031d93" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 27b74f661..fa2012811 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -79,7 +79,7 @@ flake8-isort = { version = "6.1.1", optional = true } # https://github.com/gfor black = { version = "24.8.0", optional = true } # https://github.com/psf/black pylint = { version = "3.3.1", optional = true } # https://github.com/pylint-dev/pylint pylint-django = { version = "2.5.5", optional = true } # https://github.com/PyCQA/pylint-django -pre-commit = { version = "3.8.0", optional = true } # https://github.com/pre-commit/pre-commit +pre-commit = { version = "4.0.0", optional = true } # https://github.com/pre-commit/pre-commit mypy = { version = "1.11.2", optional = true } # https://github.com/python/mypy django-stubs = { version = "5.1.0", optional = true } # https://github.com/typeddjango/django-stubs djangorestframework-stubs = { version = "3.15.1", optional = true } # https://github.com/typeddjango/djangorestframework-stubs From 1616021839c5122e66f10e1a8c991219d19b5e2f Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Mon, 7 Oct 2024 09:36:10 +0100 Subject: [PATCH 10/44] chore: reactivate end-2-end tests (#2005) * chore: reactivate end-2-end tests * fix: set workers to 3 * chore: remove frontend build * chore: remove empty lines --- .github/workflows/check_frontend.yml | 19 +++++++------------ end_to_end_tests/playwright.config.ts | 15 +++++++-------- .../tests/secobserve_test.spec.ts | 18 ++++++++---------- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/.github/workflows/check_frontend.yml b/.github/workflows/check_frontend.yml index ed41d733e..811e430d2 100644 --- a/.github/workflows/check_frontend.yml +++ b/.github/workflows/check_frontend.yml @@ -30,16 +30,11 @@ jobs: run: | npx eslint src - - name: Check build - working-directory: ./frontend + - name: End-to-end tests + working-directory: . run: | - npm run build - - # - name: End-to-end tests - # working-directory: . - # run: | - # cd end_to_end_tests - # npm install - # cd .. - # docker compose -f docker-compose-playwright.yml build - # docker compose -f docker-compose-playwright.yml up --abort-on-container-exit --exit-code-from playwright + cd end_to_end_tests + npm install + cd .. + docker compose -f docker-compose-playwright.yml build + docker compose -f docker-compose-playwright.yml up --abort-on-container-exit --exit-code-from playwright diff --git a/end_to_end_tests/playwright.config.ts b/end_to_end_tests/playwright.config.ts index 7f098fe12..13c1bedb5 100644 --- a/end_to_end_tests/playwright.config.ts +++ b/end_to_end_tests/playwright.config.ts @@ -18,7 +18,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, + // workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [['html', { open: 'never' }]], /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ @@ -30,7 +30,8 @@ export default defineConfig({ trace: 'on-first-retry', }, - timeout: 20000, + workers: 3, + timeout: 60000, /* Configure projects for major browsers */ projects: [ @@ -38,16 +39,14 @@ export default defineConfig({ name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, - { name: 'firefox', use: { ...devices['Desktop Firefox'] }, }, - - // { - // name: 'webkit', - // use: { ...devices['Desktop Safari'] }, - // }, + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, /* Test against mobile viewports. */ // { diff --git a/end_to_end_tests/tests/secobserve_test.spec.ts b/end_to_end_tests/tests/secobserve_test.spec.ts index db1c95e44..841321fb7 100644 --- a/end_to_end_tests/tests/secobserve_test.spec.ts +++ b/end_to_end_tests/tests/secobserve_test.spec.ts @@ -14,17 +14,24 @@ test.describe("SecObserve", async () => { test("Login", async () => { if (process.env.SO_PW_DOCKER) { - await delay(15000); + await delay(30000); } await page.goto(process.env.SO_PW_FRONTEND_BASE_URL); + await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/login"); + + page.on('console', msg => console.log(msg.text())); + await page.getByLabel("Username *").click(); await page.getByLabel("Username *").fill(process.env.SO_PW_USERNAME); await page.getByLabel("Username *").press("Tab"); await page.getByLabel("Password *").fill(process.env.SO_PW_PASSWORD); await page.getByRole("button", { name: "Sign in with user" }).click(); + page.on('console', msg => console.log(msg.text())); + await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/"); + await page.getByRole("menuitem", { name: "Product Groups" }).click(); await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/product_groups"); @@ -33,14 +40,5 @@ test.describe("SecObserve", async () => { await page.getByRole("menuitem", { name: "Observations" }).click(); await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/observations"); - - await page.getByRole("menuitem", { name: "Parsers" }).click(); - await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/parsers"); - - await page.getByRole("menuitem", { name: "General Rules" }).click(); - await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/general_rules"); - - await page.getByRole("menuitem", { name: "Notifications" }).click(); - await expect(page).toHaveURL(process.env.SO_PW_FRONTEND_BASE_URL + "/#/notifications"); }); }); From 1e0b434d96a2b9495e761baf015c3e9fca963b18 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 07:23:43 +0200 Subject: [PATCH 11/44] chore(deps): update actions/checkout action to v4.2.1 (#2007) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build_push_dev.yml | 2 +- .github/workflows/build_push_release.yml | 2 +- .github/workflows/check_backend.yml | 2 +- .github/workflows/check_frontend.yml | 2 +- .github/workflows/check_vulnerabilities.yml | 2 +- .github/workflows/generate_sboms.yml | 2 +- .github/workflows/publish_docs.yml | 2 +- .github/workflows/scan_sca_current.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_push_dev.yml b/.github/workflows/build_push_dev.yml index 42cce121f..45e62e58f 100644 --- a/.github/workflows/build_push_dev.yml +++ b/.github/workflows/build_push_dev.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Set up QEMU uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 diff --git a/.github/workflows/build_push_release.yml b/.github/workflows/build_push_release.yml index b85655642..b5831657e 100644 --- a/.github/workflows/build_push_release.yml +++ b/.github/workflows/build_push_release.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: 'v${{ github.event.inputs.release }}' - diff --git a/.github/workflows/check_backend.yml b/.github/workflows/check_backend.yml index cc8ebfa32..8286c74e8 100644 --- a/.github/workflows/check_backend.yml +++ b/.github/workflows/check_backend.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Set up Python 3.12 uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: diff --git a/.github/workflows/check_frontend.yml b/.github/workflows/check_frontend.yml index 811e430d2..b61dbe496 100644 --- a/.github/workflows/check_frontend.yml +++ b/.github/workflows/check_frontend.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 20 diff --git a/.github/workflows/check_vulnerabilities.yml b/.github/workflows/check_vulnerabilities.yml index 83516134b..46a5e52eb 100644 --- a/.github/workflows/check_vulnerabilities.yml +++ b/.github/workflows/check_vulnerabilities.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Run vulnerability scanners for code uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main diff --git a/.github/workflows/generate_sboms.yml b/.github/workflows/generate_sboms.yml index f0da7adc6..575803d4c 100644 --- a/.github/workflows/generate_sboms.yml +++ b/.github/workflows/generate_sboms.yml @@ -21,7 +21,7 @@ jobs: node-version: 20 - name: Checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: 'v${{ github.event.inputs.release }}' - diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 63a3c90a4..3d92b2391 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -14,7 +14,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: 3.x diff --git a/.github/workflows/scan_sca_current.yml b/.github/workflows/scan_sca_current.yml index 862e403ee..288a4339f 100644 --- a/.github/workflows/scan_sca_current.yml +++ b/.github/workflows/scan_sca_current.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: ref: 'v1.19.0' - diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a2c97db67..a0e9d72ae 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,7 +32,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: persist-credentials: false From 96cca3e710b63e968f6854645ea90a92330437db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 07:29:36 +0200 Subject: [PATCH 12/44] chore(deps): update actions/upload-artifact action to v4.4.1 (#2006) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a0e9d72ae..6cd2d2745 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1 with: name: SARIF file path: results.sarif From 53255fa3fc76b2049f8b44fe2482784a99e5cd16 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 07:34:20 +0200 Subject: [PATCH 13/44] chore(deps): update github/codeql-action action to v3.26.12 (#2008) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 6cd2d2745..77f796e52 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea # v3.26.11 + uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 with: sarif_file: results.sarif From 59825f5f2f73fe8ac08b4daec9006b37566d362e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 07:51:38 +0200 Subject: [PATCH 14/44] chore(deps): update typescript-eslint monorepo to v8.8.1 (#2009) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 88 +++++++++++++++++++------------------- frontend/package.json | 4 +- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e69c17b0a..2cf8342a1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -52,8 +52,8 @@ "@types/react": "18.3.11", "@types/react-dom": "18.3.0", "@types/recharts": "1.8.29", - "@typescript-eslint/eslint-plugin": "8.8.0", - "@typescript-eslint/parser": "8.8.0", + "@typescript-eslint/eslint-plugin": "8.8.1", + "@typescript-eslint/parser": "8.8.1", "@vitejs/plugin-react": "4.3.2", "eslint": "9.12.0", "eslint-plugin-react": "7.37.1", @@ -3263,17 +3263,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz", - "integrity": "sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz", + "integrity": "sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.8.0", - "@typescript-eslint/type-utils": "8.8.0", - "@typescript-eslint/utils": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0", + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/type-utils": "8.8.1", + "@typescript-eslint/utils": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3297,16 +3297,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.0.tgz", - "integrity": "sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz", + "integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.8.0", - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/typescript-estree": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0", + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/typescript-estree": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "debug": "^4.3.4" }, "engines": { @@ -3326,14 +3326,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz", - "integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz", + "integrity": "sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0" + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3344,14 +3344,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.0.tgz", - "integrity": "sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz", + "integrity": "sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.8.0", - "@typescript-eslint/utils": "8.8.0", + "@typescript-eslint/typescript-estree": "8.8.1", + "@typescript-eslint/utils": "8.8.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3369,9 +3369,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz", - "integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz", + "integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==", "dev": true, "license": "MIT", "engines": { @@ -3383,14 +3383,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz", - "integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz", + "integrity": "sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3438,16 +3438,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz", - "integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", + "integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.8.0", - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/typescript-estree": "8.8.0" + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/typescript-estree": "8.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3461,13 +3461,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz", - "integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz", + "integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.0", + "@typescript-eslint/types": "8.8.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { diff --git a/frontend/package.json b/frontend/package.json index f36af18cc..7e9379663 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -61,8 +61,8 @@ "@types/react": "18.3.11", "@types/react-dom": "18.3.0", "@types/recharts": "1.8.29", - "@typescript-eslint/eslint-plugin": "8.8.0", - "@typescript-eslint/parser": "8.8.0", + "@typescript-eslint/eslint-plugin": "8.8.1", + "@typescript-eslint/parser": "8.8.1", "@vitejs/plugin-react": "4.3.2", "eslint": "9.12.0", "eslint-plugin-react": "7.37.1", From ab4db4ec46b9c4f782941ab644908335e6d4d313 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 08:30:36 +0200 Subject: [PATCH 15/44] fix(deps): update dependency black to v24.10.0 (#2010) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 52 +++++++++++++++++++++--------------------- backend/pyproject.toml | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index fe0de7523..0f5632434 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -127,33 +127,33 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "black" -version = "24.8.0" +version = "24.10.0" description = "The uncompromising code formatter." optional = true -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, - {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, - {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, - {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, - {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, - {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, - {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, - {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, - {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, - {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, - {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, - {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, - {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, - {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, - {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, - {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, - {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, - {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, - {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, - {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, - {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, - {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, + {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, + {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, + {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, + {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, + {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, + {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, + {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, + {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, + {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, + {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, + {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, + {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, + {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, + {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, + {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, + {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, + {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, + {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, + {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, + {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, + {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, + {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, ] [package.dependencies] @@ -167,7 +167,7 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +d = ["aiohttp (>=3.10)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] @@ -2499,4 +2499,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "651e4f58b7567381fda994d2f62d81f5b4877ba5a2857931ebdc2849ac031d93" +content-hash = "abf21750db515317d7d5519a1d1e7a03adb287ab7ad35d7055f879c48320dbb2" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index fa2012811..c12dc93e7 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -76,7 +76,7 @@ django-coverage-plugin = { version = "3.1.0", optional = true } # https://githu # ------------------------------------------------------------------------------ flake8 = { version = "7.1.1", optional = true } # https://github.com/PyCQA/flake8 flake8-isort = { version = "6.1.1", optional = true } # https://github.com/gforcada/flake8-isort -black = { version = "24.8.0", optional = true } # https://github.com/psf/black +black = { version = "24.10.0", optional = true } # https://github.com/psf/black pylint = { version = "3.3.1", optional = true } # https://github.com/pylint-dev/pylint pylint-django = { version = "2.5.5", optional = true } # https://github.com/PyCQA/pylint-django pre-commit = { version = "4.0.0", optional = true } # https://github.com/pre-commit/pre-commit From 6690bed66c1f0fd8d7b961695d1993cc37c1d672 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 08:38:33 +0200 Subject: [PATCH 16/44] chore(deps): update dependency @types/node to v20.16.11 (#2011) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- end_to_end_tests/package-lock.json | 8 ++++---- end_to_end_tests/package.json | 2 +- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/end_to_end_tests/package-lock.json b/end_to_end_tests/package-lock.json index b9486821c..a18f6444f 100644 --- a/end_to_end_tests/package-lock.json +++ b/end_to_end_tests/package-lock.json @@ -9,7 +9,7 @@ "version": "1.19.0", "devDependencies": { "@playwright/test": "1.47.2", - "@types/node": "20.16.10" + "@types/node": "20.16.11" } }, "node_modules/@playwright/test": { @@ -29,9 +29,9 @@ } }, "node_modules/@types/node": { - "version": "20.16.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", - "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", + "version": "20.16.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", + "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/end_to_end_tests/package.json b/end_to_end_tests/package.json index 78e630c8d..6b5254a72 100644 --- a/end_to_end_tests/package.json +++ b/end_to_end_tests/package.json @@ -9,6 +9,6 @@ "author": "", "devDependencies": { "@playwright/test": "1.47.2", - "@types/node": "20.16.10" + "@types/node": "20.16.11" } } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2cf8342a1..8021aa3ea 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -47,7 +47,7 @@ "@trivago/prettier-plugin-sort-imports": "4.3.0", "@types/inflection": "1.13.2", "@types/jest": "29.5.13", - "@types/node": "20.16.10", + "@types/node": "20.16.11", "@types/prop-types": "15.7.13", "@types/react": "18.3.11", "@types/react-dom": "18.3.0", @@ -3171,9 +3171,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.16.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", - "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", + "version": "20.16.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", + "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/frontend/package.json b/frontend/package.json index 7e9379663..663d9c807 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -56,7 +56,7 @@ "@trivago/prettier-plugin-sort-imports": "4.3.0", "@types/inflection": "1.13.2", "@types/jest": "29.5.13", - "@types/node": "20.16.10", + "@types/node": "20.16.11", "@types/prop-types": "15.7.13", "@types/react": "18.3.11", "@types/react-dom": "18.3.0", From a3f06da593f5b8361d24e6b23d078ac7492d7af9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:02:56 +0200 Subject: [PATCH 17/44] fix(deps): update dependency django to v5.1.2 (#2013) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 8 ++++---- backend/pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 0f5632434..e24c68c9e 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -601,13 +601,13 @@ files = [ [[package]] name = "django" -version = "5.1.1" +version = "5.1.2" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" files = [ - {file = "Django-5.1.1-py3-none-any.whl", hash = "sha256:71603f27dac22a6533fb38d83072eea9ddb4017fead6f67f2562a40402d61c3f"}, - {file = "Django-5.1.1.tar.gz", hash = "sha256:021ffb7fdab3d2d388bc8c7c2434eb9c1f6f4d09e6119010bbb1694dda286bc2"}, + {file = "Django-5.1.2-py3-none-any.whl", hash = "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed"}, + {file = "Django-5.1.2.tar.gz", hash = "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0"}, ] [package.dependencies] @@ -2499,4 +2499,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "abf21750db515317d7d5519a1d1e7a03adb287ab7ad35d7055f879c48320dbb2" +content-hash = "9895e4f16ed818cf52d312b47c704a1156c22127d107d4ae270803051f1b7078" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c12dc93e7..4f8170e32 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -12,7 +12,7 @@ python = ">= 3.10, < 3.13" # Django # ------------------------------------------------------------------------------ gunicorn = "23.0.0" # https://github.com/benoitc/gunicorn -django = "5.1.1" # https://www.djangoproject.com/ +django = "5.1.2" # https://www.djangoproject.com/ django-environ = "0.11.2" # https://github.com/joke2k/django-environ django-filter = "24.3" # https://github.com/carltongibson/django-filter django-csp = "3.8" # https://github.com/mozilla/django-csp From 1bb7994ef6b197d268b65e1ef2f82e9185f860a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:40:04 +0200 Subject: [PATCH 18/44] fix(deps): update dependency pre-commit to v4.0.1 (#2014) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 8 ++++---- backend/pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index e24c68c9e..599df968c 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1628,13 +1628,13 @@ type = ["mypy (>=1.11.2)"] [[package]] name = "pre-commit" -version = "4.0.0" +version = "4.0.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = true python-versions = ">=3.9" files = [ - {file = "pre_commit-4.0.0-py2.py3-none-any.whl", hash = "sha256:0ca2341cf94ac1865350970951e54b1a50521e57b7b500403307aed4315a1234"}, - {file = "pre_commit-4.0.0.tar.gz", hash = "sha256:5d9807162cc5537940f94f266cbe2d716a75cfad0d78a317a92cac16287cfed6"}, + {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, + {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, ] [package.dependencies] @@ -2499,4 +2499,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "9895e4f16ed818cf52d312b47c704a1156c22127d107d4ae270803051f1b7078" +content-hash = "6a6463fcaa34149cd1decbb75dcb118057583acbed2817081b154d47330ec0d7" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 4f8170e32..4470f0b3d 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -79,7 +79,7 @@ flake8-isort = { version = "6.1.1", optional = true } # https://github.com/gfor black = { version = "24.10.0", optional = true } # https://github.com/psf/black pylint = { version = "3.3.1", optional = true } # https://github.com/pylint-dev/pylint pylint-django = { version = "2.5.5", optional = true } # https://github.com/PyCQA/pylint-django -pre-commit = { version = "4.0.0", optional = true } # https://github.com/pre-commit/pre-commit +pre-commit = { version = "4.0.1", optional = true } # https://github.com/pre-commit/pre-commit mypy = { version = "1.11.2", optional = true } # https://github.com/python/mypy django-stubs = { version = "5.1.0", optional = true } # https://github.com/typeddjango/django-stubs djangorestframework-stubs = { version = "3.15.1", optional = true } # https://github.com/typeddjango/djangorestframework-stubs From f21f2e46d30d1201a15a1dc2c2c09b12e7bb0891 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 21:07:09 +0200 Subject: [PATCH 19/44] chore(deps): update actions/cache action to v4.1.1 (#2017) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/publish_docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 3d92b2391..996ff11bc 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: 3.x - - uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 # v4.1.0 + - uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 with: key: ${{ github.ref }} path: .cache From 824c2f1f088b105c4e9223ed807617a1ddaee7f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 21:38:49 +0200 Subject: [PATCH 20/44] chore(deps): update actions/upload-artifact action to v4.4.2 (#2019) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 77f796e52..241be6133 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1 + uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 with: name: SARIF file path: results.sarif From c6bafc58dafbaa7f4c45a86ebfbd4b61f9eda030 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 21:59:09 +0200 Subject: [PATCH 21/44] chore(deps): update dependency @playwright/test to v1.48.0 (#2015) * chore(deps): update dependency @playwright/test to v1.48.0 * chore(deps): update playwright docker --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Stefan Fleckenstein --- docker-compose-playwright.yml | 2 +- end_to_end_tests/package-lock.json | 24 ++++++++++++------------ end_to_end_tests/package.json | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docker-compose-playwright.yml b/docker-compose-playwright.yml index c09dfde63..44580287a 100644 --- a/docker-compose-playwright.yml +++ b/docker-compose-playwright.yml @@ -58,7 +58,7 @@ services: playwright: - image: mcr.microsoft.com/playwright:v1.47.2 + image: mcr.microsoft.com/playwright:v1.48.0 depends_on: - frontend environment: diff --git a/end_to_end_tests/package-lock.json b/end_to_end_tests/package-lock.json index a18f6444f..871bbbef2 100644 --- a/end_to_end_tests/package-lock.json +++ b/end_to_end_tests/package-lock.json @@ -8,18 +8,18 @@ "name": "end_to_end_tests", "version": "1.19.0", "devDependencies": { - "@playwright/test": "1.47.2", + "@playwright/test": "1.48.0", "@types/node": "20.16.11" } }, "node_modules/@playwright/test": { - "version": "1.47.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz", - "integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.0.tgz", + "integrity": "sha512-W5lhqPUVPqhtc/ySvZI5Q8X2ztBOUgZ8LbAFy0JQgrXZs2xaILrUcNO3rQjwbLPfGK13+rZsDa1FpG+tqYkT5w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.47.2" + "playwright": "1.48.0" }, "bin": { "playwright": "cli.js" @@ -54,13 +54,13 @@ } }, "node_modules/playwright": { - "version": "1.47.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz", - "integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.0.tgz", + "integrity": "sha512-qPqFaMEHuY/ug8o0uteYJSRfMGFikhUysk8ZvAtfKmUK3kc/6oNl/y3EczF8OFGYIi/Ex2HspMfzYArk6+XQSA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.47.2" + "playwright-core": "1.48.0" }, "bin": { "playwright": "cli.js" @@ -73,9 +73,9 @@ } }, "node_modules/playwright-core": { - "version": "1.47.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz", - "integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.0.tgz", + "integrity": "sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/end_to_end_tests/package.json b/end_to_end_tests/package.json index 6b5254a72..ad3d60aed 100644 --- a/end_to_end_tests/package.json +++ b/end_to_end_tests/package.json @@ -8,7 +8,7 @@ "keywords": [], "author": "", "devDependencies": { - "@playwright/test": "1.47.2", + "@playwright/test": "1.48.0", "@types/node": "20.16.11" } } From 5b0a7ce669469f37b5fc1feb1907167ca80fd445 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:44:28 +0200 Subject: [PATCH 22/44] chore(deps): update dependency typescript to v5.6.3 (#2020) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8021aa3ea..bba091318 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -62,7 +62,7 @@ "globals": "15.10.0", "prettier": "3.3.3", "rewire": "7.0.0", - "typescript": "5.6.2", + "typescript": "5.6.3", "vite": "5.4.8" } }, @@ -9492,9 +9492,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/frontend/package.json b/frontend/package.json index 663d9c807..9ffd64267 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -71,7 +71,7 @@ "globals": "15.10.0", "prettier": "3.3.3", "rewire": "7.0.0", - "typescript": "5.6.2", + "typescript": "5.6.3", "vite": "5.4.8" } } From 72bd31aca99a0805d8850dd76e204acb49b28a37 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:31:09 +0200 Subject: [PATCH 23/44] fix(deps): update dependency query-string to v9.1.1 (#2021) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index bba091318..ed68f6506 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -24,7 +24,7 @@ "mermaid": "11.3.0", "oidc-client-ts": "3.1.0", "prop-types": "15.8.1", - "query-string": "9.1.0", + "query-string": "9.1.1", "ra-i18n-polyglot": "5.2.2", "ra-input-rich-text": "5.2.2", "ra-language-english": "5.2.2", @@ -7996,9 +7996,9 @@ } }, "node_modules/query-string": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.1.0.tgz", - "integrity": "sha512-t6dqMECpCkqfyv2FfwVS1xcB6lgXW/0XZSaKdsCNGYkqMO76AFiJEg4vINzoDKcZa6MS7JX+OHIjwh06K5vczw==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.1.1.tgz", + "integrity": "sha512-MWkCOVIcJP9QSKU52Ngow6bsAWAPlPK2MludXvcrS2bGZSl+T1qX9MZvRIkqUIkGLJquMJHWfsT6eRqUpp4aWg==", "license": "MIT", "dependencies": { "decode-uri-component": "^0.4.1", diff --git a/frontend/package.json b/frontend/package.json index 9ffd64267..bd23efee8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,7 +20,7 @@ "mermaid": "11.3.0", "oidc-client-ts": "3.1.0", "prop-types": "15.8.1", - "query-string": "9.1.0", + "query-string": "9.1.1", "ra-i18n-polyglot": "5.2.2", "ra-input-rich-text": "5.2.2", "ra-language-english": "5.2.2", From 284a609cbd8c8a317044adcd6cf27909c188ef09 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:35:02 +0200 Subject: [PATCH 24/44] chore(deps): update dependency globals to v15.11.0 (#2022) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ed68f6506..31295ae4d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -59,7 +59,7 @@ "eslint-plugin-react": "7.37.1", "eslint-plugin-react-hooks": "rc", "eslint-plugin-security": "3.0.1", - "globals": "15.10.0", + "globals": "15.11.0", "prettier": "3.3.3", "rewire": "7.0.0", "typescript": "5.6.3", @@ -5779,9 +5779,9 @@ } }, "node_modules/globals": { - "version": "15.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.10.0.tgz", - "integrity": "sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==", + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", "dev": true, "license": "MIT", "engines": { diff --git a/frontend/package.json b/frontend/package.json index bd23efee8..8e5da265b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -68,7 +68,7 @@ "eslint-plugin-react": "7.37.1", "eslint-plugin-react-hooks": "rc", "eslint-plugin-security": "3.0.1", - "globals": "15.10.0", + "globals": "15.11.0", "prettier": "3.3.3", "rewire": "7.0.0", "typescript": "5.6.3", From 957c16e65a35e5b27418f9ff22f81d38275b300f Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Wed, 9 Oct 2024 14:19:55 +0100 Subject: [PATCH 25/44] chore: documentation for Trivy secrets scanning (#2023) * chore: documentation for Trivy secrets scanning * chore: add trivy secrets scanning and a bit of refactoring * chore: publish docs --- .github/workflows/publish_docs.yml | 2 +- docs/assets/images/secobserve_process.drawio | 43 +++++++------- docs/assets/images/secobserve_process.svg | 2 +- .../github_actions_and_templates.md | 15 +++-- docs/integrations/supported_scanners.md | 56 ++++++++++--------- 5 files changed, 67 insertions(+), 51 deletions(-) diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 996ff11bc..59c400633 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -4,7 +4,7 @@ on: push: branches: - main - - chore/documentation_title + - chore/doc_trivy_secrets permissions: read-all diff --git a/docs/assets/images/secobserve_process.drawio b/docs/assets/images/secobserve_process.drawio index 6896bc553..91a1834aa 100644 --- a/docs/assets/images/secobserve_process.drawio +++ b/docs/assets/images/secobserve_process.drawio @@ -1,50 +1,53 @@ - + - + - + - + - + - + - - + + - + - - + + - + - - + + - - + + - - + + - - + + + + + diff --git a/docs/assets/images/secobserve_process.svg b/docs/assets/images/secobserve_process.svg index 76e2584b7..97df3073e 100644 --- a/docs/assets/images/secobserve_process.svg +++ b/docs/assets/images/secobserve_process.svg @@ -1,3 +1,3 @@ -
Project's CI/CD Pipeline
View observations
Assess observations
Upload reports manually
GitLab CI Templates / GitHub Actions
SCA


Dep. Check
Dep. Track
Grype
Trivy
SAST
Application

Bandit
ESLint
FindSecBugs
Semgrep
SAST
Infrastructure

Checkov
KICS
tfsec
Trivy
DAST


Cryptolyzer
DrHeader
ZAP
Cloud
Infastructure


Prowler
Azure Defender
Trivy Operator
Secrets


GitLeaks
Upload
Check
Security Gate
Scan
\ No newline at end of file +
Project's CI/CD Pipeline
View observations
Assess observations
Upload reports manually
GitLab CI Templates / GitHub Actions
SCA


Dep. Check
Dep. Track
Grype
Trivy (Operator)
SAST
Application

Bandit
ESLint
FindSecBugs
Semgrep
SAST
Infrastructure

Checkov
KICS
Trivy
DAST


Cryptolyzer
DrHeader
ZAP
Cloud
Infastructure


Prowler
Azure Defender
Trivy Operator
Secrets


GitLeaks
Trivy (Operator)
Upload
Check
Security Gate
Scan
\ No newline at end of file diff --git a/docs/integrations/github_actions_and_templates.md b/docs/integrations/github_actions_and_templates.md index 82560529a..8cbada45e 100644 --- a/docs/integrations/github_actions_and_templates.md +++ b/docs/integrations/github_actions_and_templates.md @@ -35,17 +35,24 @@ Most of the actions and templates use the same set of variables: | Scanner | GitHub Action | GitLab CI Template | License | |----------|---------|-------------|--------| +| **SCA** | +| [Grype](https://github.com/anchore/grype) | `actions/SCA/grype_image` | `templates/SCA/grype_image.yml` | [Apache 2.0](https://github.com/anchore/grype/blob/main/LICENSE) | +| [Trivy](https://aquasecurity.github.io/trivy) | `actions/SCA/trivy_filesystem` | `templates/SCA/trivy_filesystem.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | +| [Trivy](https://aquasecurity.github.io/trivy) | `actions/SCA/trivy_image` | `templates/SCA/trivy_image.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | +| **SAST application** | | [Bandit](https://bandit.readthedocs.io/en/latest) | `actions/SAST/bandit` | `templates/SAST/bandit.yml` | [Apache 2.0](https://github.com/PyCQA/bandit/blob/main/LICENSE) | | [ESLint](https://github.com/eslint/eslint) | `actions/SAST/eslint` | `templates/SAST/eslint.yml` | [MIT](https://github.com/eslint/eslint/blob/main/LICENSE) | | [Semgrep](https://semgrep.dev/docs) | `actions/SAST/semgrep` | `templates/SAST/semgrep.yml` |[LGPL 2.1](https://github.com/returntocorp/semgrep/blob/develop/LICENSE) | +| **SAST infrastructure** | | [Checkov](https://www.checkov.io/1.Welcome/Quick%20Start.html) | `actions/SAST/checkov` | `templates/SAST/checkov.yml` | [Apache 2.0](https://github.com/bridgecrewio/checkov/blob/main/LICENSE) | | [KICS](https://docs.kics.io/latest) | `actions/SAST/kics` | `templates/SAST/kics.yml` | [Apache 2.0](https://github.com/Checkmarx/kics/blob/master/LICENSE) | | [tfsec](https://aquasecurity.github.io/tfsec) | `actions/SAST/tfsec` | `templates/SAST/tfsec.yml` | [MIT](https://github.com/aquasecurity/tfsec/blob/master/LICENSE) | -| [Trivy](https://aquasecurity.github.io/trivy) | `actions/SCA/trivy_config` | `templates/SCA/trivy_config.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | -| [Grype](https://github.com/anchore/grype) | `actions/SCA/grype_image` | `templates/SCA/grype_image.yml` | [Apache 2.0](https://github.com/anchore/grype/blob/main/LICENSE) | -| [Trivy](https://aquasecurity.github.io/trivy) | `actions/SCA/trivy_filesystem` | `templates/SCA/trivy_filesystem.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | -| [Trivy](https://aquasecurity.github.io/trivy) | `actions/SCA/trivy_image` | `templates/SCA/trivy_image.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | +| [Trivy](https://aquasecurity.github.io/trivy) | `actions/SAST/trivy_config` | `templates/SAST/trivy_config.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | +| **Secrets** | | [Gitleaks](https://gitleaks.io) | `actions/secrets/gitleaks` | `templates/secrets/gitleaks.yml` | [MIT](https://github.com/gitleaks/gitleaks/blob/master/LICENSE) | +| [Trivy](https://aquasecurity.github.io/trivy) | `actions/secrets/trivy_filesystem_secrets` | `templates/secrets/trivy_filesystem_secrets.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | +| [Trivy](https://aquasecurity.github.io/trivy) | `actions/secrets/trivy_image_secrets` | `templates/secrets/trivy_image_secrets.yml` | [Apache 2.0](https://github.com/aquasecurity/trivy/blob/main/LICENSE) | +| **DAST** | | [CryptoLyzer](https://gitlab.com/coroner/cryptolyzer) | `actions/DAST/cryptolyzer` | `templates/DAST/cryptolyzer.yml` | [MPL 2.0](https://gitlab.com/coroner/cryptolyzer/-/blob/master/LICENSE.txt) | | [DrHeader](https://github.com/Santandersecurityresearch/DrHeader) | `actions/DAST/drheader` | `templates/DAST/drheader.yml` | [MIT](https://github.com/Santandersecurityresearch/DrHeader/blob/master/LICENSE) | | [ZAP](https://github.com/zaproxy/zaproxy) | `actions/DAST/zap` | `templates/DAST/zap.yml` | [Apache 2.0](https://github.com/zaproxy/zaproxy/blob/main/LICENSE) | diff --git a/docs/integrations/supported_scanners.md b/docs/integrations/supported_scanners.md index 6ab936242..542e8c019 100644 --- a/docs/integrations/supported_scanners.md +++ b/docs/integrations/supported_scanners.md @@ -5,8 +5,8 @@ There are different types of vulnerability scans: * **SCA / Software Composition Analysis**: Modern systems are not completely rewritten from scratch, but many basic functions are used as libraries. This applies not only to application code, but in the case of Docker, also to operating system functions and programmes. All these components can have known vulnerabilities that can be exploited by attackers. -* **Application SAST / Static Application Security Testing**: Many problems can be detected in the code through rule-based searches, e.g. injections or weak encryption. Tools exist for all common programming languages. -* **Infrastructure SAST**: Also for Infrastructure as Code (Dockerfile, Helm Charts, Terraform, ...) many problems can be found with rule-based searches before applying the code to set up the infrastructure. +* **SAST application / Static Application Security Testing**: Many problems can be detected in the code through rule-based searches, e.g. injections or weak encryption. Tools exist for all common programming languages. +* **SAST infrastructure**: Also for Infrastructure as Code (Dockerfile, Helm Charts, Terraform, ...) many problems can be found with rule-based searches before applying the code to set up the infrastructure. * **Secrets**: Secrets such as passwords or API keys must not be checked into repositories with the code, and there are tools that search, for example, Git repositories across the entire version history for such secrets. * **DAST / Dynamic Application Security Testing:**: This class is black-box security testing where the tests are performed by attacking an application (typically web applications or APIs) from the outside. The tests can be passive, where only anomalies are looked for, or active attacks on the system. * **Cloud infrastructure:** The running infrastructure, e.g. a Kubernetes cluster, can also be checked for vulnerabilities both with internal views (tests that run inside the infrastructure) and external views (tests from outside via the internet). @@ -25,29 +25,35 @@ This means the `CycloneDX` and `SARIF` parsers can import data from a variety of These scanners have been tested with SecObserve: -| Scanner | Parser | Type | Source | -|--------|---------|------|--------| -| [Dependency Track](https://dependencytrack.org) | Dependency Track | SCA | [API](../integrations/api_import.md#dependency-track) | -| [Trivy Operator Prometheus](https://github.com/aquasecurity/trivy-operator) | JSON | Cloud infrastructure | [API](../integrations/api_import.md#trivy-operator-prometheus) | -| [Dependency Check](https://jeremylong.github.io/DependencyCheck) | SARIF ^1)^ | SCA | File | -| [Grype](https://github.com/anchore/grype) | CycloneDX | SCA | File | -| [Trivy](https://aquasecurity.github.io/trivy) | CycloneDX | SCA | File | -| [Bandit](https://bandit.readthedocs.io/en/latest) | SARIF | Application SAST | File | -| [ESLint](https://github.com/nodesecurity/eslint-plugin-security) | SARIF | Application SAST | File | -| [Find-Sec-Bugs](https://find-sec-bugs.github.io) | SARIF | Application SAST | File | -| [Semgrep](https://semgrep.dev/docs) | SARIF | Application SAST | File | -| [Checkov](https://www.checkov.io/1.Welcome/Quick%20Start.html) | SARIF | Infrastructure SAST | File | -| [KICS](https://docs.kics.io/latest) | SARIF | Infrastructure SAST | File | -| [tfsec](https://aquasecurity.github.io/tfsec) | SARIF | Infrastructure SAST | File | -| [Trivy](https://aquasecurity.github.io/trivy) | SARIF | Infrastructure SAST | File | -| [Trivy](https://aquasecurity.github.io/trivy) | SARIF | Secrets | File | -| [Gitleaks](https://gitleaks.io) | SARIF | Secrets | File | -| [CryptoLyzer](https://gitlab.com/coroner/cryptolyzer) ^2)^ | CryptoLyzer | DAST | File | -| [DrHeader](https://github.com/Santandersecurityresearch/DrHeader) | DrHeader | DAST | File | -| [ZAP](https://www.zaproxy.org) | ZAP | DAST | File | -| [Azure Defender for Cloud](https://learn.microsoft.com/en-us/azure/defender-for-cloud/) ^3)^ | Azure Defender | Cloud infrastructure | File | -| [Prowler 3](https://github.com/prowler-cloud/prowler)| Prowler 3 | Cloud infrastructure | File | -| [Prowler 4](https://github.com/prowler-cloud/prowler)| OCSF (Open Cybersecurity Schema Framework) | Cloud infrastructure | File | +| Scanner | Parser | Source | +|--------|---------|--------| +| **SCA** | +| [Dependency Track](https://dependencytrack.org) | Dependency Track | [API](../integrations/api_import.md#dependency-track) | +| [Dependency Check](https://jeremylong.github.io/DependencyCheck) | SARIF ^1)^ | File | +| [Grype](https://github.com/anchore/grype) | CycloneDX | File | +| [Trivy](https://aquasecurity.github.io/trivy) | CycloneDX | File | +| **SAST application** | +| [Bandit](https://bandit.readthedocs.io/en/latest) | SARIF | File | +| [ESLint](https://github.com/nodesecurity/eslint-plugin-security) | SARIF | File | +| [Find-Sec-Bugs](https://find-sec-bugs.github.io) | SARIF | File | +| [Semgrep](https://semgrep.dev/docs) | SARIF | File | +| **SAST infrastructure** | +| [Checkov](https://www.checkov.io/1.Welcome/Quick%20Start.html) | SARIF | File | +| [KICS](https://docs.kics.io/latest) | SARIF | File | +| [tfsec](https://aquasecurity.github.io/tfsec) | SARIF | File | +| [Trivy](https://aquasecurity.github.io/trivy) | SARIF | File | +| **Secrets** | +| [Gitleaks](https://gitleaks.io) | SARIF | File | +| [Trivy](https://aquasecurity.github.io/trivy) | SARIF | File | +| **DAST** | +| [CryptoLyzer](https://gitlab.com/coroner/cryptolyzer) ^2)^ | CryptoLyzer | File | +| [DrHeader](https://github.com/Santandersecurityresearch/DrHeader) | DrHeader | File | +| [ZAP](https://www.zaproxy.org) | ZAP | File | +| **Cloud infrastructure** | +| [Azure Defender for Cloud](https://learn.microsoft.com/en-us/azure/defender-for-cloud/) ^3)^ | Azure Defender | File | +| [Prowler 3](https://github.com/prowler-cloud/prowler)| Prowler 3 | File | +| [Prowler 4](https://github.com/prowler-cloud/prowler)| OCSF (Open Cybersecurity Schema Framework) | File | +| [Trivy Operator Prometheus](https://github.com/aquasecurity/trivy-operator) | JSON | [API](../integrations/api_import.md#trivy-operator-prometheus) | ^1)^ This is the exception to the rule. Even though SARIF is more suited for static code analysis, it works for Dependency Check. From d983ade7ccea35a082cc88efa9078380a5f197ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:33:47 +0200 Subject: [PATCH 26/44] fix(deps): update dependency coverage to v7.6.2 (#2024) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 140 +++++++++++++++++++---------------------- backend/pyproject.toml | 2 +- 2 files changed, 66 insertions(+), 76 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 599df968c..5cd40c6bf 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -398,83 +398,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.1" +version = "7.6.2" description = "Code coverage measurement for Python" optional = true -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, - {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, - {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, - {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, - {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, - {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, - {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, - {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, - {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, - {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, - {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, - {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, - {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, - {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, - {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, - {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, - {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, - {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, + {file = "coverage-7.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667"}, + {file = "coverage-7.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345"}, + {file = "coverage-7.6.2-cp310-cp310-win32.whl", hash = "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676"}, + {file = "coverage-7.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02"}, + {file = "coverage-7.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b"}, + {file = "coverage-7.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0"}, + {file = "coverage-7.6.2-cp311-cp311-win32.whl", hash = "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438"}, + {file = "coverage-7.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b"}, + {file = "coverage-7.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c"}, + {file = "coverage-7.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b"}, + {file = "coverage-7.6.2-cp312-cp312-win32.whl", hash = "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276"}, + {file = "coverage-7.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0"}, + {file = "coverage-7.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40"}, + {file = "coverage-7.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869"}, + {file = "coverage-7.6.2-cp313-cp313-win32.whl", hash = "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530"}, + {file = "coverage-7.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36"}, + {file = "coverage-7.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef"}, + {file = "coverage-7.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db"}, + {file = "coverage-7.6.2-cp313-cp313t-win32.whl", hash = "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171"}, + {file = "coverage-7.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a"}, + {file = "coverage-7.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5"}, + {file = "coverage-7.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627"}, + {file = "coverage-7.6.2-cp39-cp39-win32.whl", hash = "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0"}, + {file = "coverage-7.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c"}, + {file = "coverage-7.6.2-pp39.pp310-none-any.whl", hash = "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e"}, + {file = "coverage-7.6.2.tar.gz", hash = "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3"}, ] [package.extras] @@ -2499,4 +2489,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "6a6463fcaa34149cd1decbb75dcb118057583acbed2817081b154d47330ec0d7" +content-hash = "16450a9ac278d1e785613e9ff8db3fc1bed725eaeeb3e73f0c87ca5cc4b9f5ad" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 4470f0b3d..1b0e7b52d 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -69,7 +69,7 @@ django-extensions = { version = "3.2.3", optional = true } # https://github.com # Unittest dependencies # ------------------------------------------------------------------------------ -coverage = { version = "7.6.1", optional = true } # https://github.com/nedbat/coveragepy +coverage = { version = "7.6.2", optional = true } # https://github.com/nedbat/coveragepy django-coverage-plugin = { version = "3.1.0", optional = true } # https://github.com/nedbat/django_coverage_plugin # Code quality dependencies From 891fc89091987ec6c6c4ebdd2ef50891a45eef78 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:10:04 +0200 Subject: [PATCH 27/44] chore(deps): update actions/upload-artifact action to v4.4.3 (#2025) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 241be6133..296b5434c 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif From c412edff96bf41ef446501ffbae78d6423ca4dc3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:51:06 +0200 Subject: [PATCH 28/44] chore(deps): update traefik docker tag to v3.1.6 (#2026) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- docker-compose-prod-mysql.yml | 2 +- docker-compose-prod-postgres.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-prod-mysql.yml b/docker-compose-prod-mysql.yml index 84fa485d8..c2a98597f 100644 --- a/docker-compose-prod-mysql.yml +++ b/docker-compose-prod-mysql.yml @@ -10,7 +10,7 @@ networks: services: traefik: - image: "traefik:v3.1.5" + image: "traefik:v3.1.6" container_name: "prod_traefik" command: - "--log.level=INFO" diff --git a/docker-compose-prod-postgres.yml b/docker-compose-prod-postgres.yml index 1cd8c77e7..7a9f0c09f 100644 --- a/docker-compose-prod-postgres.yml +++ b/docker-compose-prod-postgres.yml @@ -10,7 +10,7 @@ networks: services: traefik: - image: "traefik:v3.1.5" + image: "traefik:v3.1.6" container_name: "prod_traefik" command: - "--log.level=INFO" From 2f08f63b86bda266e5312d04d93c8d9faa5de325 Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Thu, 10 Oct 2024 11:06:15 +0100 Subject: [PATCH 29/44] feat: show products (groups) for users and authorization groups (#2027) --- .../access_control/api/serializers.py | 42 +++- backend/application/core/api/filters.py | 7 +- .../core/api/serializers_product.py | 22 +- ...test_authorization_authorization_groups.py | 20 +- ...ion_product_authorization_group_members.py | 12 +- .../api/test_authorization_product_members.py | 14 +- .../api/test_authorization_users.py | 8 +- .../AuthorizationGroupShow.tsx | 27 ++- .../src/access_control/users/UserShow.tsx | 192 +++++++++++------- .../ProductAuthorizationGroupMemberDelete.tsx | 2 +- .../ProductAuthorizationGroupMemberEdit.tsx | 2 +- ...ctAuthorizationGroupMemberEmbeddedList.tsx | 23 ++- ...ctAuthorizationGroupMemberEmbeddedList.tsx | 66 ++++++ .../ProductMemberEmbeddedList.tsx | 19 +- .../UserProductMemberEmbeddedList.tsx | 63 ++++++ 15 files changed, 391 insertions(+), 128 deletions(-) create mode 100644 frontend/src/core/product_authorization_group_members/UserProductAuthorizationGroupMemberEmbeddedList.tsx create mode 100644 frontend/src/core/product_members/UserProductMemberEmbeddedList.tsx diff --git a/backend/application/access_control/api/serializers.py b/backend/application/access_control/api/serializers.py index 819884917..b71a4de84 100644 --- a/backend/application/access_control/api/serializers.py +++ b/backend/application/access_control/api/serializers.py @@ -14,7 +14,7 @@ from application.access_control.services.authorization import get_user_permissions from application.access_control.services.roles_permissions import Permissions, Roles from application.commons.services.global_request import get_current_user -from application.core.models import Product_Member +from application.core.models import Product_Authorization_Group_Member, Product_Member class NestedAuthorizationGroupSerializer(ModelSerializer): @@ -24,6 +24,7 @@ class Meta: class UserListSerializer(ModelSerializer): + full_name = SerializerMethodField() permissions = SerializerMethodField() has_password = SerializerMethodField() @@ -71,6 +72,12 @@ def to_representation(self, instance: User): return data + def get_full_name(self, obj: User) -> str: + if not obj.is_active: + return f"{obj.full_name} (inactive)" + + return obj.full_name + def get_permissions(self, obj: User) -> list[Permissions]: return get_user_permissions(obj) @@ -84,7 +91,10 @@ def get_has_password(self, obj: User) -> bool: class UserSerializer(UserListSerializer): + full_name = SerializerMethodField() authorization_groups = NestedAuthorizationGroupSerializer(many=True) + has_product_group_members = SerializerMethodField() + has_product_members = SerializerMethodField() class Meta: model = User @@ -107,6 +117,8 @@ class Meta: "date_joined", "has_password", "authorization_groups", + "has_product_group_members", + "has_product_members", ] def to_representation(self, instance: User): @@ -115,9 +127,24 @@ def to_representation(self, instance: User): user = get_current_user() if user and not user.is_superuser and not user.pk == instance.pk: data.pop("authorization_groups") + data.pop("has_product_group_members") + data.pop("has_product_members") return data + def get_full_name(self, obj: User) -> str: + return obj.full_name + + def get_has_product_group_members(self, obj: User) -> bool: + return Product_Member.objects.filter( + user=obj, product__is_product_group=True + ).exists() + + def get_has_product_members(self, obj: User) -> bool: + return Product_Member.objects.filter( + user=obj, product__is_product_group=False + ).exists() + class UserUpdateSerializer(ModelSerializer): class Meta: @@ -146,10 +173,23 @@ class UserPasswortRulesSerializer(Serializer): class AuthorizationGroupSerializer(ModelSerializer): + has_product_group_members = SerializerMethodField() + has_product_members = SerializerMethodField() + class Meta: model = Authorization_Group fields = "__all__" + def get_has_product_group_members(self, obj: Authorization_Group) -> bool: + return Product_Authorization_Group_Member.objects.filter( + authorization_group=obj, product__is_product_group=True + ).exists() + + def get_has_product_members(self, obj: Authorization_Group) -> bool: + return Product_Authorization_Group_Member.objects.filter( + authorization_group=obj, product__is_product_group=False + ).exists() + class AuthorizationGroupUserSerializer(Serializer): user = IntegerField(validators=[MinValueValidator(0)]) diff --git a/backend/application/core/api/filters.py b/backend/application/core/api/filters.py index e3d07b3e9..78938a5e9 100644 --- a/backend/application/core/api/filters.py +++ b/backend/application/core/api/filters.py @@ -2,6 +2,7 @@ from django.utils import timezone from django_filters import ( + BooleanFilter, CharFilter, ChoiceFilter, FilterSet, @@ -100,11 +101,13 @@ class Meta: class ProductMemberFilter(FilterSet): product = NumberFilter(field_name="product") + is_product_group = BooleanFilter(field_name="product__is_product_group") ordering = OrderingFilter( # tuple-mapping retains order fields=( ("user__full_name", "user_data.full_name"), + ("product__name", "product_data.name"), ("role", "role"), ), ) @@ -116,11 +119,13 @@ class Meta: class ProductAuthorizationGroupMemberFilter(FilterSet): product = NumberFilter(field_name="product") + is_product_group = BooleanFilter(field_name="product__is_product_group") ordering = OrderingFilter( # tuple-mapping retains order fields=( - ("authorization_group__name", "authorization_group_name"), + ("authorization_group__name", "authorization_group_data.name"), + ("product__name", "product_data.name"), ("role", "role"), ), ) diff --git a/backend/application/core/api/serializers_product.py b/backend/application/core/api/serializers_product.py index 4bb6ecbfb..85f648b13 100644 --- a/backend/application/core/api/serializers_product.py +++ b/backend/application/core/api/serializers_product.py @@ -7,7 +7,10 @@ ValidationError, ) -from application.access_control.api.serializers import UserListSerializer +from application.access_control.api.serializers import ( + NestedAuthorizationGroupSerializer, + UserListSerializer, +) from application.access_control.services.authorization import get_highest_user_role from application.access_control.services.roles_permissions import ( Permissions, @@ -384,6 +387,12 @@ def get_risk_acceptance_expiry_date_calculated( return calculate_risk_acceptance_expiry_date(obj) +class NestedProductSerializerSmall(ModelSerializer): + class Meta: + model = Product + fields = ["id", "name", "is_product_group"] + + class NestedProductListSerializer(ModelSerializer): product_group_name = SerializerMethodField() @@ -399,6 +408,7 @@ def get_product_group_name(self, obj: Product) -> str: class ProductMemberSerializer(ModelSerializer): user_data = UserListSerializer(source="user", read_only=True) + product_data = NestedProductSerializerSmall(source="product", read_only=True) class Meta: model = Product_Member @@ -446,17 +456,15 @@ def validate(self, attrs: dict): class ProductAuthorizationGroupMemberSerializer(ModelSerializer): - authorization_group_name = SerializerMethodField() + authorization_group_data = NestedAuthorizationGroupSerializer( + source="authorization_group", read_only=True + ) + product_data = NestedProductSerializerSmall(source="product", read_only=True) class Meta: model = Product_Authorization_Group_Member fields = "__all__" - def get_authorization_group_name( - self, obj: Product_Authorization_Group_Member - ) -> str: - return obj.authorization_group.name - def validate(self, attrs: dict): self.instance: Product_Authorization_Group_Member data_product: Optional[Product] = attrs.get("product") diff --git a/backend/unittests/access_control/api/test_authorization_authorization_groups.py b/backend/unittests/access_control/api/test_authorization_authorization_groups.py index 409491436..85dbd7de4 100644 --- a/backend/unittests/access_control/api/test_authorization_authorization_groups.py +++ b/backend/unittests/access_control/api/test_authorization_authorization_groups.py @@ -11,7 +11,7 @@ class TestAuthorizationAuthorizationGroups(TestAuthorizationBase): def test_authorization_authorization_groups(self): prepare_authorization_groups() - expected_data = "{'count': 5, 'next': None, 'previous': None, 'results': [{'id': 4, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}, {'id': 5, 'name': 'db_group_internal_read', 'oidc_group': '', 'users': [3]}, {'id': 6, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}, {'id': 7, 'name': 'db_group_product_group', 'oidc_group': '', 'users': [6]}, {'id': 8, 'name': 'db_group_unused', 'oidc_group': '', 'users': []}]}" + expected_data = "{'count': 5, 'next': None, 'previous': None, 'results': [{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}, {'id': 5, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_read', 'oidc_group': '', 'users': [3]}, {'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}, {'id': 7, 'has_product_group_members': True, 'has_product_members': False, 'name': 'db_group_product_group', 'oidc_group': '', 'users': [6]}, {'id': 8, 'has_product_group_members': False, 'has_product_members': False, 'name': 'db_group_unused', 'oidc_group': '', 'users': []}]}" self._test_api( APITest( "db_admin", @@ -23,8 +23,8 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 4, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}]}" - expected_data_product_group = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 7, 'name': 'db_group_product_group', 'oidc_group': '', 'users': [6]}]}" + expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}]}" + expected_data_product_group = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 7, 'has_product_group_members': True, 'has_product_members': False, 'name': 'db_group_product_group', 'oidc_group': '', 'users': [6]}]}" self._test_api( APITest( "db_internal_write", @@ -36,7 +36,7 @@ def test_authorization_authorization_groups(self): expected_data_product_group=expected_data_product_group, ) ) - expected_data = "{'id': 4, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}" + expected_data = "{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}" self._test_api( APITest( "db_internal_write", @@ -60,7 +60,7 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 6, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}]}" + expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}]}" self._test_api( APITest( "db_external", @@ -71,9 +71,7 @@ def test_authorization_authorization_groups(self): expected_data, ) ) - expected_data = ( - "{'id': 6, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}" - ) + expected_data = "{'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}" self._test_api( APITest( "db_external", @@ -96,7 +94,7 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = "{'id': 9, 'name': 'string', 'oidc_group': 'oidc', 'users': []}" + expected_data = "{'id': 9, 'has_product_group_members': False, 'has_product_members': False, 'name': 'string', 'oidc_group': 'oidc', 'users': []}" self._test_api( APITest( "db_admin", @@ -130,9 +128,7 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = ( - "{'id': 9, 'name': 'changed_string', 'oidc_group': 'oidc', 'users': []}" - ) + expected_data = "{'id': 9, 'has_product_group_members': False, 'has_product_members': False, 'name': 'changed_string', 'oidc_group': 'oidc', 'users': []}" self._test_api( APITest( "db_admin", diff --git a/backend/unittests/access_control/api/test_authorization_product_authorization_group_members.py b/backend/unittests/access_control/api/test_authorization_product_authorization_group_members.py index 5b2b3123c..cc9824f54 100644 --- a/backend/unittests/access_control/api/test_authorization_product_authorization_group_members.py +++ b/backend/unittests/access_control/api/test_authorization_product_authorization_group_members.py @@ -11,7 +11,7 @@ class TestAuthorizationProductMembers(TestAuthorizationBase): def test_authorization_product_authorization_group_members(self): prepare_authorization_groups() - expected_data = "{'count': 4, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_name': 'db_group_internal_write', 'role': 5, 'product': 1, 'authorization_group': 4}, {'id': 2, 'authorization_group_name': 'db_group_internal_read', 'role': 1, 'product': 1, 'authorization_group': 5}, {'id': 3, 'authorization_group_name': 'db_group_external', 'role': 5, 'product': 2, 'authorization_group': 6}, {'id': 4, 'authorization_group_name': 'db_group_product_group', 'role': 5, 'product': 3, 'authorization_group': 7}]}" + expected_data = "{'count': 4, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_data': {'id': 4, 'name': 'db_group_internal_write', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'authorization_group': 4}, {'id': 2, 'authorization_group_data': {'id': 5, 'name': 'db_group_internal_read', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 1, 'product': 1, 'authorization_group': 5}, {'id': 3, 'authorization_group_data': {'id': 6, 'name': 'db_group_external', 'oidc_group': ''}, 'product_data': {'id': 2, 'name': 'db_product_external', 'is_product_group': False}, 'role': 5, 'product': 2, 'authorization_group': 6}, {'id': 4, 'authorization_group_data': {'id': 7, 'name': 'db_group_product_group', 'oidc_group': ''}, 'product_data': {'id': 3, 'name': 'db_product_group', 'is_product_group': True}, 'role': 5, 'product': 3, 'authorization_group': 7}]}" self._test_api( APITest( "db_admin", @@ -23,7 +23,7 @@ def test_authorization_product_authorization_group_members(self): ) ) - expected_data = "{'count': 2, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_name': 'db_group_internal_write', 'role': 5, 'product': 1, 'authorization_group': 4}, {'id': 2, 'authorization_group_name': 'db_group_internal_read', 'role': 1, 'product': 1, 'authorization_group': 5}]}" + expected_data = "{'count': 2, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_data': {'id': 4, 'name': 'db_group_internal_write', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'authorization_group': 4}, {'id': 2, 'authorization_group_data': {'id': 5, 'name': 'db_group_internal_read', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 1, 'product': 1, 'authorization_group': 5}]}" self._test_api( APITest( "db_internal_write", @@ -36,7 +36,7 @@ def test_authorization_product_authorization_group_members(self): ) ) - expected_data = "{'count': 3, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_name': 'db_group_internal_write', 'role': 5, 'product': 1, 'authorization_group': 4}, {'id': 2, 'authorization_group_name': 'db_group_internal_read', 'role': 1, 'product': 1, 'authorization_group': 5}, {'id': 4, 'authorization_group_name': 'db_group_product_group', 'role': 5, 'product': 3, 'authorization_group': 7}]}" + expected_data = "{'count': 3, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_data': {'id': 4, 'name': 'db_group_internal_write', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'authorization_group': 4}, {'id': 2, 'authorization_group_data': {'id': 5, 'name': 'db_group_internal_read', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 1, 'product': 1, 'authorization_group': 5}, {'id': 4, 'authorization_group_data': {'id': 7, 'name': 'db_group_product_group', 'oidc_group': ''}, 'product_data': {'id': 3, 'name': 'db_product_group', 'is_product_group': True}, 'role': 5, 'product': 3, 'authorization_group': 7}]}" self._test_api( APITest( "db_product_group_user", @@ -47,7 +47,7 @@ def test_authorization_product_authorization_group_members(self): expected_data, ) ) - expected_data = "{'id': 1, 'authorization_group_name': 'db_group_internal_write', 'role': 5, 'product': 1, 'authorization_group': 4}" + expected_data = "{'id': 1, 'authorization_group_data': {'id': 4, 'name': 'db_group_internal_write', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'authorization_group': 4}" self._test_api( APITest( "db_internal_write", @@ -96,7 +96,7 @@ def test_authorization_product_authorization_group_members(self): expected_data, ) ) - expected_data = "{'id': 5, 'authorization_group_name': 'db_group_unused', 'role': 3, 'product': 1, 'authorization_group': 8}" + expected_data = "{'id': 5, 'authorization_group_data': {'id': 8, 'name': 'db_group_unused', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 3, 'product': 1, 'authorization_group': 8}" self._test_api( APITest( "db_internal_write", @@ -123,7 +123,7 @@ def test_authorization_product_authorization_group_members(self): ) ) - expected_data = "{'id': 2, 'authorization_group_name': 'db_group_internal_read', 'role': 2, 'product': 1, 'authorization_group': 5}" + expected_data = "{'id': 2, 'authorization_group_data': {'id': 5, 'name': 'db_group_internal_read', 'oidc_group': ''}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 2, 'product': 1, 'authorization_group': 5}" self._test_api( APITest( "db_internal_write", diff --git a/backend/unittests/access_control/api/test_authorization_product_members.py b/backend/unittests/access_control/api/test_authorization_product_members.py index 41a5560e1..9ef825ae3 100644 --- a/backend/unittests/access_control/api/test_authorization_product_members.py +++ b/backend/unittests/access_control/api/test_authorization_product_members.py @@ -6,14 +6,14 @@ class TestAuthorizationProductMembers(TestAuthorizationBase): def test_authorization_product_members(self): - expected_data = "{'count': 5, 'next': None, 'previous': None, 'results': [{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'role': 5, 'product': 1, 'user': 2}, {'id': 2, 'user_data': {'id': 3, 'username': 'db_internal_read', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_read', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:25:06+01:00', 'has_password': False}, 'role': 1, 'product': 1, 'user': 3}, {'id': 3, 'user_data': {'id': 4, 'username': 'db_external', 'first_name': '', 'last_name': '', 'full_name': 'db_external', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': True, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-12T19:48:08.514000+01:00', 'has_password': False}, 'role': 5, 'product': 2, 'user': 4}, {'id': 4, 'user_data': {'id': 3, 'username': 'db_internal_read', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_read', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:25:06+01:00', 'has_password': False}, 'role': 1, 'product': 2, 'user': 3}, {'id': 6, 'user_data': {'id': 6, 'username': 'db_product_group_user', 'first_name': '', 'last_name': '', 'full_name': 'db_product_group_user', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-04T11:09:18.495000+01:00', 'has_password': True}, 'role': 5, 'product': 3, 'user': 6}]}" + expected_data = "{'count': 5, 'next': None, 'previous': None, 'results': [{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'user': 2}, {'id': 2, 'user_data': {'id': 3, 'username': 'db_internal_read', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_read', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:25:06+01:00', 'has_password': False}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 1, 'product': 1, 'user': 3}, {'id': 3, 'user_data': {'id': 4, 'username': 'db_external', 'first_name': '', 'last_name': '', 'full_name': 'db_external', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': True, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-12T19:48:08.514000+01:00', 'has_password': False}, 'product_data': {'id': 2, 'name': 'db_product_external', 'is_product_group': False}, 'role': 5, 'product': 2, 'user': 4}, {'id': 4, 'user_data': {'id': 3, 'username': 'db_internal_read', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_read', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:25:06+01:00', 'has_password': False}, 'product_data': {'id': 2, 'name': 'db_product_external', 'is_product_group': False}, 'role': 1, 'product': 2, 'user': 3}, {'id': 6, 'user_data': {'id': 6, 'username': 'db_product_group_user', 'first_name': '', 'last_name': '', 'full_name': 'db_product_group_user', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-04T11:09:18.495000+01:00', 'has_password': True}, 'product_data': {'id': 3, 'name': 'db_product_group', 'is_product_group': True}, 'role': 5, 'product': 3, 'user': 6}]}" self._test_api( APITest( "db_admin", "get", "/api/product_members/", None, 200, expected_data ) ) - expected_data = "{'count': 2, 'next': None, 'previous': None, 'results': [{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'role': 5, 'product': 1, 'user': 2}, {'id': 2, 'user_data': {'id': 3, 'username': 'db_internal_read', 'full_name': 'db_internal_read'}, 'role': 1, 'product': 1, 'user': 3}]}" + expected_data = "{'count': 2, 'next': None, 'previous': None, 'results': [{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'user': 2}, {'id': 2, 'user_data': {'id': 3, 'username': 'db_internal_read', 'full_name': 'db_internal_read'}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 1, 'product': 1, 'user': 3}]}" self._test_api( APITest( "db_internal_write", @@ -26,7 +26,7 @@ def test_authorization_product_members(self): ) ) - expected_data = "{'count': 3, 'next': None, 'previous': None, 'results': [{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'full_name': 'db_internal_write'}, 'role': 5, 'product': 1, 'user': 2}, {'id': 2, 'user_data': {'id': 3, 'username': 'db_internal_read', 'full_name': 'db_internal_read'}, 'role': 1, 'product': 1, 'user': 3}, {'id': 6, 'user_data': {'id': 6, 'username': 'db_product_group_user', 'first_name': '', 'last_name': '', 'full_name': 'db_product_group_user', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-04T11:09:18.495000+01:00', 'has_password': True}, 'role': 5, 'product': 3, 'user': 6}]}" + expected_data = "{'count': 3, 'next': None, 'previous': None, 'results': [{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'full_name': 'db_internal_write'}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'user': 2}, {'id': 2, 'user_data': {'id': 3, 'username': 'db_internal_read', 'full_name': 'db_internal_read'}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 1, 'product': 1, 'user': 3}, {'id': 6, 'user_data': {'id': 6, 'username': 'db_product_group_user', 'first_name': '', 'last_name': '', 'full_name': 'db_product_group_user', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-04T11:09:18.495000+01:00', 'has_password': True}, 'product_data': {'id': 3, 'name': 'db_product_group', 'is_product_group': True}, 'role': 5, 'product': 3, 'user': 6}]}" self._test_api( APITest( "db_product_group_user", @@ -37,8 +37,8 @@ def test_authorization_product_members(self): expected_data, ) ) - expected_data = "{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'role': 5, 'product': 1, 'user': 2}" - expected_data_product_group = "{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'full_name': 'db_internal_write'}, 'role': 5, 'product': 1, 'user': 2}" + expected_data = "{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'user': 2}" + expected_data_product_group = "{'id': 1, 'user_data': {'id': 2, 'username': 'db_internal_write', 'full_name': 'db_internal_write'}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 5, 'product': 1, 'user': 2}" self._test_api( APITest( username="db_internal_write", @@ -89,7 +89,7 @@ def test_authorization_product_members(self): expected_data, ) ) - expected_data = "{'id': 7, 'user_data': {'id': 1, 'username': 'db_admin', 'full_name': 'db_admin'}, 'role': 3, 'product': 1, 'user': 1}" + expected_data = "{'id': 7, 'user_data': {'id': 1, 'username': 'db_admin', 'full_name': 'db_admin'}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 3, 'product': 1, 'user': 1}" self._test_api( APITest( "db_internal_write", @@ -116,7 +116,7 @@ def test_authorization_product_members(self): ) ) - expected_data = "{'id': 7, 'user_data': {'id': 1, 'username': 'db_admin', 'full_name': 'db_admin'}, 'role': 2, 'product': 1, 'user': 1}" + expected_data = "{'id': 7, 'user_data': {'id': 1, 'username': 'db_admin', 'full_name': 'db_admin'}, 'product_data': {'id': 1, 'name': 'db_product_internal', 'is_product_group': False}, 'role': 2, 'product': 1, 'user': 1}" self._test_api( APITest( "db_internal_write", diff --git a/backend/unittests/access_control/api/test_authorization_users.py b/backend/unittests/access_control/api/test_authorization_users.py index 30f992096..383f4f156 100644 --- a/backend/unittests/access_control/api/test_authorization_users.py +++ b/backend/unittests/access_control/api/test_authorization_users.py @@ -33,7 +33,7 @@ def test_authorization_users(self): ) ) - expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}]}" + expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}], 'has_product_group_members': False, 'has_product_members': True}" expected_data_product_group = "{'id': 2, 'username': 'db_internal_write', 'full_name': 'db_internal_write'}" self._test_api( APITest( @@ -64,7 +64,7 @@ def test_authorization_users(self): self._test_api( APITest("db_external", "get", "/api/users/", None, 200, expected_data) ) - expected_data = "{'id': 4, 'username': 'db_external', 'first_name': '', 'last_name': '', 'full_name': 'db_external', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': True, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-12T19:48:08.514000+01:00', 'has_password': False, 'authorization_groups': []}" + expected_data = "{'id': 4, 'username': 'db_external', 'first_name': '', 'last_name': '', 'full_name': 'db_external', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': True, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-12T19:48:08.514000+01:00', 'has_password': False, 'authorization_groups': [], 'has_product_group_members': False, 'has_product_members': True}" self._test_api( APITest("db_external", "get", "/api/users/4/", None, 200, expected_data) ) @@ -214,7 +214,7 @@ def test_authorization_users(self): ) ) - expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}]}" + expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}], 'has_product_group_members': False, 'has_product_members': True}" self._test_api( APITest( "db_internal_write", @@ -228,7 +228,7 @@ def test_authorization_users(self): ) post_data = {"setting_theme": "dark"} - expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'dark', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}]}" + expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'dark', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}], 'has_product_group_members': False, 'has_product_members': True}" self._test_api( APITest( "db_internal_write", diff --git a/frontend/src/access_control/authorization_groups/AuthorizationGroupShow.tsx b/frontend/src/access_control/authorization_groups/AuthorizationGroupShow.tsx index 2dd1f3366..e0c326d8c 100644 --- a/frontend/src/access_control/authorization_groups/AuthorizationGroupShow.tsx +++ b/frontend/src/access_control/authorization_groups/AuthorizationGroupShow.tsx @@ -4,6 +4,7 @@ import { EditButton, Labeled, PrevNextButtons, Show, TextField, TopToolbar, With import { is_superuser } from "../../commons/functions"; import { useStyles } from "../../commons/layout/themes"; +import UserProductAuthorizationGroupMemberEmbeddedList from "../../core/product_authorization_group_members/UserProductAuthorizationGroupMemberEmbeddedList"; import UserAGEmbeddedList from "../users/UserAGEmbeddedList"; const ShowActions = () => { @@ -29,7 +30,7 @@ const AuthorizationGroupComponent = () => { ( - + Authorization Group @@ -44,12 +45,34 @@ const AuthorizationGroupComponent = () => { )} - + Users + {authorization_group.has_product_group_members && ( + + + Product Groups + + + + )} + {authorization_group.has_product_members && ( + + + Products + + + + )} )} /> diff --git a/frontend/src/access_control/users/UserShow.tsx b/frontend/src/access_control/users/UserShow.tsx index 1d4d2c7c6..ef011ced5 100644 --- a/frontend/src/access_control/users/UserShow.tsx +++ b/frontend/src/access_control/users/UserShow.tsx @@ -17,6 +17,8 @@ import { import { is_superuser } from "../../commons/functions"; import { useStyles } from "../../commons/layout/themes"; +import { getSettingListSize } from "../../commons/user_settings/functions"; +import UserProductMemberEmbeddedList from "../../core/product_members/UserProductMemberEmbeddedList"; import UserChangePassword from "./UserChangePassword"; const ShowActions = () => { @@ -66,101 +68,133 @@ const UserComponent = () => { const { classes } = useStyles(); const current_user = localStorage.getItem("user"); + const showFullInformation = (user: any) => { + return is_superuser() || (current_user && JSON.parse(current_user).id == user.id); + }; + + const userWidth = (user: any) => { + return showFullInformation(user) ? "50%" : "100%"; + }; + return ( ( - - - User - - - - - - - - - {user.first_name && ( - - - - )} - {user.last_name && ( - - - - )} - {user.email && ( - - - - )} - {user.date_joined && ( - - - - )} - {user.has_password != undefined && ( - - - - )} - {user.is_oidc_user != undefined && ( - - - - )} + + + + + User + + + + + + + + + {user.first_name && ( + + + + )} + {user.last_name && ( + + + + )} + {user.email && ( + + + + )} + {user.date_joined && ( + + + + )} + {user.has_password != undefined && ( + + + + )} + {user.is_oidc_user != undefined && ( + + + + )} + + - - {(is_superuser() || (current_user && JSON.parse(current_user).id == user.id)) && ( - + {showFullInformation(user) && ( + + + + Permissions + + + + + + + + + + + + + + + + Settings + + + {user.setting_theme && ( + + + + )} + {user.setting_list_size && ( + + + + )} + + + + )} + + {showFullInformation(user) && user.authorization_groups && user.authorization_groups.length > 0 && ( + - Permissions + Authorization Groups - - - - - - - - - - - + + + + + {" "} + )} - {(is_superuser() || (current_user && JSON.parse(current_user).id == user.id)) && ( - + {showFullInformation(user) && user.has_product_group_members && ( + - Settings + Product Groups - - {user.setting_theme && ( - - - - )} - {user.setting_list_size && ( - - - - )} - + )} - {(is_superuser() || (current_user && JSON.parse(current_user).id == user.id)) && ( + {showFullInformation(user) && user.has_product_members && ( - Groups + Products - - - - - {" "} - + )} diff --git a/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberDelete.tsx b/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberDelete.tsx index f36823f13..45c5a0d1e 100644 --- a/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberDelete.tsx +++ b/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberDelete.tsx @@ -43,7 +43,7 @@ const ProductAuthorizationGroupMemberDelete = (props: ProductAuthorizationGroupM title="Delete authorization group member" content={ "Are you sure you want to delete the authorization group member " + - props.product_authorization_group_member.authorization_group_name + + props.product_authorization_group_member.authorization_group_data.name + "?" } onConfirm={handleConfirm} diff --git a/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEdit.tsx b/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEdit.tsx index caa394cae..912e2f9c9 100644 --- a/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEdit.tsx +++ b/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEdit.tsx @@ -85,7 +85,7 @@ const ProductAuthorizationGroupMemberEdit = () => { Edit authorization group member }> - + diff --git a/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEmbeddedList.tsx b/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEmbeddedList.tsx index 394aca2b4..1b38939f7 100644 --- a/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEmbeddedList.tsx +++ b/frontend/src/core/product_authorization_group_members/ProductAuthorizationGroupMemberEmbeddedList.tsx @@ -1,5 +1,5 @@ import { Stack } from "@mui/material"; -import { Datagrid, ListContextProvider, SelectField, TextField, WithRecord, useListController } from "react-admin"; +import { Datagrid, Identifier, ListContextProvider, SelectField, WithRecord, useListController } from "react-admin"; import { PERMISSION_PRODUCT_AUTHORIZATION_GROUP_MEMBER_DELETE, @@ -7,6 +7,7 @@ import { ROLE_CHOICES, } from "../../access_control/types"; import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; +import TextUrlField from "../../commons/custom_fields/TextUrlField"; import { getSettingListSize } from "../../commons/user_settings/functions"; import ProductAuthorizationGroupMemberDelete from "./ProductAuthorizationGroupMemberDelete"; import ProductAuthorizationGroupMemberEdit from "./ProductAuthorizationGroupMemberEdit"; @@ -15,14 +16,17 @@ type ProductAuthorizationGroupMemberEmbeddedListProps = { product: any; }; +const showAuthorizationGroup = (id: Identifier) => { + return "#/authorization_groups/" + id + "/show"; +}; + const ProductAuthorizationGroupMemberEmbeddedList = ({ product }: ProductAuthorizationGroupMemberEmbeddedListProps) => { const listContext = useListController({ filter: { product: Number(product.id) }, perPage: 25, resource: "product_authorization_group_members", - sort: { field: "authorization_group_name", order: "ASC" }, + sort: { field: "authorization_group_data.name", order: "ASC" }, disableSyncWithLocation: true, - storeKey: "product_authorization_group_member.embedded", }); if (listContext.isLoading) { @@ -39,7 +43,18 @@ const ProductAuthorizationGroupMemberEmbeddedList = ({ product }: ProductAuthori rowClick={false} resource="product_authorization_group_members" > - + ( + + )} + /> ( diff --git a/frontend/src/core/product_authorization_group_members/UserProductAuthorizationGroupMemberEmbeddedList.tsx b/frontend/src/core/product_authorization_group_members/UserProductAuthorizationGroupMemberEmbeddedList.tsx new file mode 100644 index 000000000..c11365f6a --- /dev/null +++ b/frontend/src/core/product_authorization_group_members/UserProductAuthorizationGroupMemberEmbeddedList.tsx @@ -0,0 +1,66 @@ +import { + Datagrid, + Identifier, + ListContextProvider, + RaRecord, + SelectField, + TextField, + useListController, +} from "react-admin"; + +import { ROLE_CHOICES } from "../../access_control/types"; +import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; +import { getSettingListSize } from "../../commons/user_settings/functions"; + +type UserProductAuthorizationGroupMemberEmbeddedListProps = { + authorization_group: any; + is_product_group: boolean; +}; + +function productLabel(is_product_group: boolean): string { + return is_product_group ? "Product Group" : "Product"; +} + +const showProduct = (id: Identifier, resource: string, record: RaRecord) => { + if (record.product_data.is_product_group) { + return "../../../../product_groups/" + record.product_data.id + "/show/members"; + } + return "../../../../products/" + record.product_data.id + "/show/members"; +}; + +const UserProductAuthorizationGroupMemberEmbeddedList = ({ + authorization_group, + is_product_group, +}: UserProductAuthorizationGroupMemberEmbeddedListProps) => { + const listContext = useListController({ + filter: { authorization_group: Number(authorization_group.id), is_product_group: is_product_group }, + perPage: 25, + resource: "product_authorization_group_members", + sort: { field: "product_data.name", order: "ASC" }, + disableSyncWithLocation: true, + }); + + if (listContext.isLoading) { + return
Loading...
; + } + + return ( + +
+ + + + + +
+
+ ); +}; + +export default UserProductAuthorizationGroupMemberEmbeddedList; diff --git a/frontend/src/core/product_members/ProductMemberEmbeddedList.tsx b/frontend/src/core/product_members/ProductMemberEmbeddedList.tsx index 4baf6e0ec..af43321c8 100644 --- a/frontend/src/core/product_members/ProductMemberEmbeddedList.tsx +++ b/frontend/src/core/product_members/ProductMemberEmbeddedList.tsx @@ -1,5 +1,5 @@ import { Stack } from "@mui/material"; -import { Datagrid, ListContextProvider, SelectField, TextField, WithRecord, useListController } from "react-admin"; +import { Datagrid, Identifier, ListContextProvider, SelectField, WithRecord, useListController } from "react-admin"; import { PERMISSION_PRODUCT_MEMBER_DELETE, @@ -7,6 +7,7 @@ import { ROLE_CHOICES, } from "../../access_control/types"; import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; +import TextUrlField from "../../commons/custom_fields/TextUrlField"; import { getSettingListSize } from "../../commons/user_settings/functions"; import ProductMemberDelete from "./ProductMemberDelete"; import ProductMemberEdit from "./ProductMemberEdit"; @@ -15,6 +16,10 @@ type ProductMemberEmbeddedListProps = { product: any; }; +const showUser = (id: Identifier) => { + return "#/users/" + id + "/show"; +}; + const ProductMemberEmbeddedList = ({ product }: ProductMemberEmbeddedListProps) => { const listContext = useListController({ filter: { product: Number(product.id) }, @@ -22,7 +27,6 @@ const ProductMemberEmbeddedList = ({ product }: ProductMemberEmbeddedListProps) resource: "product_members", sort: { field: "user_data.full_name", order: "ASC" }, disableSyncWithLocation: true, - storeKey: "product_member.embedded", }); if (listContext.isLoading) { @@ -39,7 +43,16 @@ const ProductMemberEmbeddedList = ({ product }: ProductMemberEmbeddedListProps) rowClick={false} resource="product_members" > - + ( + + )} + /> ( diff --git a/frontend/src/core/product_members/UserProductMemberEmbeddedList.tsx b/frontend/src/core/product_members/UserProductMemberEmbeddedList.tsx new file mode 100644 index 000000000..1aae10cd4 --- /dev/null +++ b/frontend/src/core/product_members/UserProductMemberEmbeddedList.tsx @@ -0,0 +1,63 @@ +import { + Datagrid, + Identifier, + ListContextProvider, + RaRecord, + SelectField, + TextField, + useListController, +} from "react-admin"; + +import { ROLE_CHOICES } from "../../access_control/types"; +import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; +import { getSettingListSize } from "../../commons/user_settings/functions"; + +type UserProductMemberEmbeddedListProps = { + user: any; + is_product_group: boolean; +}; + +function productLabel(is_product_group: boolean): string { + return is_product_group ? "Product Group" : "Product"; +} + +const showProduct = (id: Identifier, resource: string, record: RaRecord) => { + if (record.product_data.is_product_group) { + return "../../../../product_groups/" + record.product_data.id + "/show/members"; + } + return "../../../../products/" + record.product_data.id + "/show/members"; +}; + +const UserProductMemberEmbeddedList = ({ user, is_product_group }: UserProductMemberEmbeddedListProps) => { + const listContext = useListController({ + filter: { user: Number(user.id), is_product_group: is_product_group }, + perPage: 25, + resource: "product_members", + sort: { field: "product_data.name", order: "ASC" }, + disableSyncWithLocation: true, + }); + + if (listContext.isLoading) { + return
Loading...
; + } + + return ( + +
+ + + + + +
+
+ ); +}; + +export default UserProductMemberEmbeddedList; From a14d7febf2434c2d25a700f8ec1b14de37407423 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:12:23 +0200 Subject: [PATCH 30/44] chore(deps): update maibornwolff/secobserve_actions_templates digest to 70451f5 (#2018) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build_push_dev.yml | 2 +- .github/workflows/build_push_release.yml | 4 ++-- .github/workflows/check_vulnerabilities.yml | 2 +- .github/workflows/scan_sca_current.yml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_push_dev.yml b/.github/workflows/build_push_dev.yml index 45e62e58f..8c4f35a7d 100644 --- a/.github/workflows/build_push_dev.yml +++ b/.github/workflows/build_push_dev.yml @@ -52,7 +52,7 @@ jobs: VERSION=dev - name: Run SCA vulnerability scanners - uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main + uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main with: so_configuration: 'so_configuration_sca_dev.yml' SO_API_TOKEN: ${{ secrets.SO_API_TOKEN }} diff --git a/.github/workflows/build_push_release.yml b/.github/workflows/build_push_release.yml index b5831657e..e076b1c74 100644 --- a/.github/workflows/build_push_release.yml +++ b/.github/workflows/build_push_release.yml @@ -64,13 +64,13 @@ jobs: VERSION=${{ github.event.inputs.release }} - name: Run vulnerability scanners for images - uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main + uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main with: so_configuration: 'so_configuration_sca_current.yml' SO_API_TOKEN: ${{ secrets.SO_API_TOKEN }} - name: Run vulnerability scanners for endpoints - uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main + uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main with: so_configuration: 'so_configuration_endpoints.yml' SO_API_TOKEN: ${{ secrets.SO_API_TOKEN }} diff --git a/.github/workflows/check_vulnerabilities.yml b/.github/workflows/check_vulnerabilities.yml index 46a5e52eb..8d0c5d0d7 100644 --- a/.github/workflows/check_vulnerabilities.yml +++ b/.github/workflows/check_vulnerabilities.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Run vulnerability scanners for code - uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main + uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main with: so_configuration: 'so_configuration_code.yml' SO_API_TOKEN: ${{ secrets.SO_API_TOKEN }} diff --git a/.github/workflows/scan_sca_current.yml b/.github/workflows/scan_sca_current.yml index 288a4339f..2549ed6e4 100644 --- a/.github/workflows/scan_sca_current.yml +++ b/.github/workflows/scan_sca_current.yml @@ -18,13 +18,13 @@ jobs: ref: 'v1.19.0' - name: Run SCA vulnerability scanners - uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main + uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main with: so_configuration: 'so_configuration_sca_current.yml' SO_API_TOKEN: ${{ secrets.SO_API_TOKEN }} - name: Run endpoint vulnerability scanners - uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@cca1b2fcc133cf278996436bc61db3ac5031c9fc # main + uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main with: so_configuration: 'so_configuration_endpoints.yml' SO_API_TOKEN: ${{ secrets.SO_API_TOKEN }} From 89e33cd89ef9a0d3f2808d923094b05d794f9a5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:48:05 +0200 Subject: [PATCH 31/44] chore(deps): update dependency mkdocs-material to v9.5.40 (#2028) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- mkdocs_requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs_requirements.txt b/mkdocs_requirements.txt index 166be22a7..fc3c6cb9f 100644 --- a/mkdocs_requirements.txt +++ b/mkdocs_requirements.txt @@ -1 +1 @@ -mkdocs-material==9.5.39 # https://github.com/squidfunk/mkdocs-material +mkdocs-material==9.5.40 # https://github.com/squidfunk/mkdocs-material From 914347d89a9ee91c99476504b7447df2db72cd0b Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Thu, 10 Oct 2024 12:16:07 +0100 Subject: [PATCH 32/44] chore: small ui changes (#2029) --- .../users/UserAGEmbeddedList.tsx | 17 ++++++++-- .../src/core/observations/ObservationShow.tsx | 4 ++- .../product_groups/ProductGroupHeader.tsx | 28 +++++++++------ frontend/src/core/products/ProductHeader.tsx | 34 ++++++++++++------- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/frontend/src/access_control/users/UserAGEmbeddedList.tsx b/frontend/src/access_control/users/UserAGEmbeddedList.tsx index 82d21e233..5139dab43 100644 --- a/frontend/src/access_control/users/UserAGEmbeddedList.tsx +++ b/frontend/src/access_control/users/UserAGEmbeddedList.tsx @@ -2,15 +2,16 @@ import { BooleanField, Datagrid, FilterForm, + Identifier, ListContextProvider, NullableBooleanInput, - TextField, TextInput, WithRecord, useListController, } from "react-admin"; import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; +import TextUrlField from "../../commons/custom_fields/TextUrlField"; import { is_superuser } from "../../commons/functions"; import { getSettingListSize } from "../../commons/user_settings/functions"; import AuthorizationGroupUserAdd from "../authorization_groups/AuthorizationGroupUserAdd"; @@ -31,6 +32,10 @@ function listFilters() { } } +const showUser = (id: Identifier) => { + return "#/users/" + id + "/show"; +}; + type UserAGEmbeddedListProps = { authorization_group: any; }; @@ -60,8 +65,14 @@ const UserAGEmbeddedList = ({ authorization_group }: UserAGEmbeddedListProps) => {is_superuser() && } - - + } + /> + } + /> {is_superuser() && } {is_superuser() && } {is_superuser() && } diff --git a/frontend/src/core/observations/ObservationShow.tsx b/frontend/src/core/observations/ObservationShow.tsx index f8b247800..7a1e11685 100644 --- a/frontend/src/core/observations/ObservationShow.tsx +++ b/frontend/src/core/observations/ObservationShow.tsx @@ -108,7 +108,9 @@ const ObservationShowComponent = () => { render={(observation) => ( - Observation + + Observation + diff --git a/frontend/src/core/product_groups/ProductGroupHeader.tsx b/frontend/src/core/product_groups/ProductGroupHeader.tsx index a8c7c520c..5d1beb085 100644 --- a/frontend/src/core/product_groups/ProductGroupHeader.tsx +++ b/frontend/src/core/product_groups/ProductGroupHeader.tsx @@ -1,4 +1,4 @@ -import { Paper } from "@mui/material"; +import { Box, Paper, Typography } from "@mui/material"; import { Labeled, RecordContextProvider, TextField, useGetOne } from "react-admin"; import { useParams } from "react-router-dom"; @@ -15,19 +15,27 @@ const ProductGroupHeader = () => { - - - - - - + + Product Group + + + + + + + + + ); diff --git a/frontend/src/core/products/ProductHeader.tsx b/frontend/src/core/products/ProductHeader.tsx index ace02dec4..37ea327aa 100644 --- a/frontend/src/core/products/ProductHeader.tsx +++ b/frontend/src/core/products/ProductHeader.tsx @@ -1,4 +1,4 @@ -import { Paper } from "@mui/material"; +import { Box, Paper, Typography } from "@mui/material"; import { Labeled, RecordContextProvider, TextField, useGetOne } from "react-admin"; import { useParams } from "react-router-dom"; @@ -23,24 +23,32 @@ const ProductHeader = () => { - - - - {product && product.security_gate_passed != undefined && ( + + Product + + + + + + {product && product.security_gate_passed != undefined && ( + + + + )} - + - )} - - - + ); From d1e304829bdbbb8c9c0ddd727c33ae92295bcc5b Mon Sep 17 00:00:00 2001 From: Lukas Voetmand Date: Fri, 11 Oct 2024 13:37:13 +0200 Subject: [PATCH 33/44] feat: zoom buttons for dependency graph (#2030) * feat: zoom buttons for dependency graph * fix: changed zoom icons --- .../observations/Mermaid_Dependencies.tsx | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/frontend/src/core/observations/Mermaid_Dependencies.tsx b/frontend/src/core/observations/Mermaid_Dependencies.tsx index 1fe829100..c9968c1bc 100644 --- a/frontend/src/core/observations/Mermaid_Dependencies.tsx +++ b/frontend/src/core/observations/Mermaid_Dependencies.tsx @@ -1,5 +1,7 @@ +import AddIcon from "@mui/icons-material/Add"; import CloseIcon from "@mui/icons-material/Close"; -import { Dialog, DialogContent, DialogTitle, Divider, IconButton, Stack } from "@mui/material"; +import RemoveIcon from "@mui/icons-material/Remove"; +import { Dialog, DialogContent, DialogTitle, Divider, IconButton, Paper, Stack } from "@mui/material"; import mermaid from "mermaid"; import { Fragment, useEffect, useState } from "react"; import { Labeled, WrapperField, useRecordContext } from "react-admin"; @@ -13,6 +15,12 @@ mermaid.initialize({ }, }); +function resizeDependencyGraph(scale: number) { + const img = document.getElementById("dependency-graph-svg-in-dialog") as HTMLImageElement; + img.setAttribute("width", `${img.width * scale}`); + img.setAttribute("height", `${img.height * scale}`); +} + const GraphSVG = () => { const svg = document.querySelector(".mermaid svg"); if (svg == null) { @@ -22,7 +30,7 @@ const GraphSVG = () => { const blob = new Blob([svgData], { type: "image/svg+xml" }); const url = URL.createObjectURL(blob); console.log(url); - return Component dependency graph not available; + return Component dependency graph not available; }; const createMermaidGraph = (dependencies_str: string) => { @@ -132,6 +140,15 @@ const MermaidDependencies = () => { + + resizeDependencyGraph(1.1)}> + + + + resizeDependencyGraph(0.9)}> + + + From 7a760b72b18e89bbbbcde28613985247b78c84ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 13:48:49 +0200 Subject: [PATCH 34/44] fix(deps): update dependency pylint-django to v2.6.1 (#2031) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 12 ++++++------ backend/pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 5cd40c6bf..8074905fd 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1932,17 +1932,17 @@ testutils = ["gitpython (>3)"] [[package]] name = "pylint-django" -version = "2.5.5" +version = "2.6.1" description = "A Pylint plugin to help Pylint understand the Django web framework" optional = true -python-versions = ">=3.7,<4.0" +python-versions = "<4.0,>=3.9" files = [ - {file = "pylint_django-2.5.5-py3-none-any.whl", hash = "sha256:5abd5c2228e0e5e2a4cb6d0b4fc1d1cef1e773d0be911412f4dd4fc1a1a440b7"}, - {file = "pylint_django-2.5.5.tar.gz", hash = "sha256:2f339e4bf55776958283395c5139c37700c91bd5ef1d8251ef6ac88b5abbba9b"}, + {file = "pylint-django-2.6.1.tar.gz", hash = "sha256:19e8c85a8573a04e3de7be2ba91e9a7c818ebf05e1b617be2bbae67a906b725f"}, + {file = "pylint_django-2.6.1-py3-none-any.whl", hash = "sha256:359f68fe8c810ee6bc8e1ab4c83c19b15a43b234a24b08978f47a23462b5ce28"}, ] [package.dependencies] -pylint = ">=2.0,<4" +pylint = ">=3.0,<4" pylint-plugin-utils = ">=0.8" [package.extras] @@ -2489,4 +2489,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "16450a9ac278d1e785613e9ff8db3fc1bed725eaeeb3e73f0c87ca5cc4b9f5ad" +content-hash = "023efa21c4edac8f874422236180767f8f1b62438434a68ca7f17e0615f3ec0c" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 1b0e7b52d..20a4fdf96 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -78,7 +78,7 @@ flake8 = { version = "7.1.1", optional = true } # https://github.com/PyCQA/flak flake8-isort = { version = "6.1.1", optional = true } # https://github.com/gforcada/flake8-isort black = { version = "24.10.0", optional = true } # https://github.com/psf/black pylint = { version = "3.3.1", optional = true } # https://github.com/pylint-dev/pylint -pylint-django = { version = "2.5.5", optional = true } # https://github.com/PyCQA/pylint-django +pylint-django = { version = "2.6.1", optional = true } # https://github.com/PyCQA/pylint-django pre-commit = { version = "4.0.1", optional = true } # https://github.com/pre-commit/pre-commit mypy = { version = "1.11.2", optional = true } # https://github.com/python/mypy django-stubs = { version = "5.1.0", optional = true } # https://github.com/typeddjango/django-stubs From 4609dab9888fa929c69df0f8e0150117e50efcf1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 07:10:41 +0200 Subject: [PATCH 35/44] chore(deps): update dependency @types/react-dom to v18.3.1 (#2032) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 31295ae4d..c01f7ff7a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -50,7 +50,7 @@ "@types/node": "20.16.11", "@types/prop-types": "15.7.13", "@types/react": "18.3.11", - "@types/react-dom": "18.3.0", + "@types/react-dom": "18.3.1", "@types/recharts": "1.8.29", "@typescript-eslint/eslint-plugin": "8.8.1", "@typescript-eslint/parser": "8.8.1", @@ -3203,9 +3203,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/frontend/package.json b/frontend/package.json index 8e5da265b..0876e25ea 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -59,7 +59,7 @@ "@types/node": "20.16.11", "@types/prop-types": "15.7.13", "@types/react": "18.3.11", - "@types/react-dom": "18.3.0", + "@types/react-dom": "18.3.1", "@types/recharts": "1.8.29", "@typescript-eslint/eslint-plugin": "8.8.1", "@typescript-eslint/parser": "8.8.1", From c6d5fdb060bf7626419c4664e49ee5269b554627 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 09:01:11 +0200 Subject: [PATCH 36/44] fix(deps): update react-admin monorepo to v5.2.3 (#2033) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 57 +++++++++++++++++++------------------- frontend/package.json | 8 +++--- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c01f7ff7a..b2755122e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -25,11 +25,11 @@ "oidc-client-ts": "3.1.0", "prop-types": "15.8.1", "query-string": "9.1.1", - "ra-i18n-polyglot": "5.2.2", - "ra-input-rich-text": "5.2.2", - "ra-language-english": "5.2.2", + "ra-i18n-polyglot": "5.2.3", + "ra-input-rich-text": "5.2.3", + "ra-language-english": "5.2.3", "react": "18.3.1", - "react-admin": "5.2.2", + "react-admin": "5.2.3", "react-chartjs-2": "5.2.0", "react-dom": "18.3.1", "react-hook-form": "7.53.0", @@ -8034,9 +8034,9 @@ "license": "MIT" }, "node_modules/ra-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ra-core/-/ra-core-5.2.2.tgz", - "integrity": "sha512-X2wZ5cg+TYDCuyO0aFAhvg+aqxb2/xQzxCuTnC3HR+9hCYXjckwjQAs3yjJwkdLLrOAS+w8/aiKMy5tZPbh95Q==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ra-core/-/ra-core-5.2.3.tgz", + "integrity": "sha512-uaJX54igNS9VPK1jiSfwjtDaW6P70cxuZvRBBPqqNoN04fldVHUKUaC7wY/LsWnIRCPATz+TU93RaKYDUNw8FQ==", "license": "MIT", "dependencies": { "@tanstack/react-query": "^5.8.4", @@ -8105,19 +8105,19 @@ } }, "node_modules/ra-i18n-polyglot": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ra-i18n-polyglot/-/ra-i18n-polyglot-5.2.2.tgz", - "integrity": "sha512-D9elwYgelAVw5cnAsNyhUHMr+Y0N0+4yDx7vSR78bxzll07C95Tw0ZruFIp5Wa4vTPmvnKpX+yiwiJ/TqU88rg==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ra-i18n-polyglot/-/ra-i18n-polyglot-5.2.3.tgz", + "integrity": "sha512-e7njr3BtPLdqQaqlWdjqjYWEWPZ4qca9QCVQBSxMkIZNoUf1mbKTHq+TDfnlCgnSKmADS9l8FRIcP+7fV6RNEQ==", "license": "MIT", "dependencies": { "node-polyglot": "^2.2.2", - "ra-core": "^5.2.2" + "ra-core": "^5.2.3" } }, "node_modules/ra-input-rich-text": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ra-input-rich-text/-/ra-input-rich-text-5.2.2.tgz", - "integrity": "sha512-q54bwse0zLmRnIM9v/cQeiojpaAxhHwOmGtpaTsUiz0NTWHyGepI080fG68DrYHXJGoOXZ03PJHQUUQaDuqBig==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ra-input-rich-text/-/ra-input-rich-text-5.2.3.tgz", + "integrity": "sha512-TtImIvhLZDIqnyijkKqZA13QYkxorEANjvu2xwb4W0V8/VR8shjadscHWEmqNyps6nFnU22mjgZDQKOOvXzPow==", "license": "MIT", "dependencies": { "@tiptap/core": "^2.0.3", @@ -8144,18 +8144,18 @@ } }, "node_modules/ra-language-english": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-5.2.2.tgz", - "integrity": "sha512-dbCAv5ELaCWmh2raf6VIWWuQK3Z+IQ3jrlatgdipjTse57I0zu7Rp5WwlOdYfWRk6pA3WsMvHHrkuZNEWroDyg==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-5.2.3.tgz", + "integrity": "sha512-MkY5kWUtAmQVwvGA674UcY1X7cops8Bmk8PshHIGFlhNNJR4rlrNcl1n4Ypt9M18SbGWhltYvjYMpcILdtKdjQ==", "license": "MIT", "dependencies": { - "ra-core": "^5.2.2" + "ra-core": "^5.2.3" } }, "node_modules/ra-ui-materialui": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-5.2.2.tgz", - "integrity": "sha512-RpMKa9C+VLeH8fDLHJ4jVZv6eYPsqBqO+D3NpC6vYI9dkFfX62E74UqVEOI98/IADURNxeG2cuSVBrwS+gtZKg==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-5.2.3.tgz", + "integrity": "sha512-H2KOBzbjTv81iryRL8V17cQHihWVAzRkO2xa1D4+SmjJRAtYPrel46BqtOgHbgT3/3TeuMNIbCPF9sWm7JlRvg==", "license": "MIT", "dependencies": { "@tanstack/react-query": "^5.8.4", @@ -8175,6 +8175,7 @@ "peerDependencies": { "@mui/icons-material": "^5.15.20", "@mui/material": "^5.15.20", + "@mui/utils": "^5.15.20", "ra-core": "^5.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", @@ -8248,19 +8249,19 @@ } }, "node_modules/react-admin": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/react-admin/-/react-admin-5.2.2.tgz", - "integrity": "sha512-fYsfLAGNo7wf3zlLUS2k+/3uxPdz68lwuyAGLnnHjHR55e0uGvj1m6BrM/ma/YhTmUjpvetNLbWBQj8GZWWjrw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/react-admin/-/react-admin-5.2.3.tgz", + "integrity": "sha512-rUtk86O1SCIlXkTfLYrzSyJe2xIqanI+7R/xRkWX2Aodw3OGxMBsdzyScqa9Bn9CbyhDSVlZHVCSHNf9a5PWlA==", "license": "MIT", "dependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@mui/icons-material": "^5.15.20", "@mui/material": "^5.15.20", - "ra-core": "^5.2.2", - "ra-i18n-polyglot": "^5.2.2", - "ra-language-english": "^5.2.2", - "ra-ui-materialui": "^5.2.2", + "ra-core": "^5.2.3", + "ra-i18n-polyglot": "^5.2.3", + "ra-language-english": "^5.2.3", + "ra-ui-materialui": "^5.2.3", "react-hook-form": "^7.53.0", "react-router": "^6.22.0", "react-router-dom": "^6.22.0" diff --git a/frontend/package.json b/frontend/package.json index 0876e25ea..15864fa20 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,11 +21,11 @@ "oidc-client-ts": "3.1.0", "prop-types": "15.8.1", "query-string": "9.1.1", - "ra-i18n-polyglot": "5.2.2", - "ra-input-rich-text": "5.2.2", - "ra-language-english": "5.2.2", + "ra-i18n-polyglot": "5.2.3", + "ra-input-rich-text": "5.2.3", + "ra-language-english": "5.2.3", "react": "18.3.1", - "react-admin": "5.2.2", + "react-admin": "5.2.3", "react-chartjs-2": "5.2.0", "react-dom": "18.3.1", "react-hook-form": "7.53.0", From f472edc63e2cd2837fb8f185c01ac8aaf4d0ae3f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 09:08:35 +0200 Subject: [PATCH 37/44] fix(deps): update react-router monorepo to v6.27.0 (#2034) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- frontend/package-lock.json | 28 ++++++++++++++-------------- frontend/package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b2755122e..97c89c6da 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -34,8 +34,8 @@ "react-dom": "18.3.1", "react-hook-form": "7.53.0", "react-oidc-context": "3.2.0", - "react-router": "6.26.2", - "react-router-dom": "6.26.2", + "react-router": "6.27.0", + "react-router-dom": "6.27.0", "runtime-env-cra": "file:lib/runtime-env-cra", "tss-react": "4.9.13" }, @@ -2117,9 +2117,9 @@ "license": "MIT" }, "node_modules/@remix-run/router": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", - "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", + "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -8369,12 +8369,12 @@ } }, "node_modules/react-router": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz", - "integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", + "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.19.2" + "@remix-run/router": "1.20.0" }, "engines": { "node": ">=14.0.0" @@ -8384,13 +8384,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz", - "integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", + "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.19.2", - "react-router": "6.26.2" + "@remix-run/router": "1.20.0", + "react-router": "6.27.0" }, "engines": { "node": ">=14.0.0" diff --git a/frontend/package.json b/frontend/package.json index 15864fa20..c93298a7f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,8 +30,8 @@ "react-dom": "18.3.1", "react-hook-form": "7.53.0", "react-oidc-context": "3.2.0", - "react-router": "6.26.2", - "react-router-dom": "6.26.2", + "react-router": "6.27.0", + "react-router-dom": "6.27.0", "runtime-env-cra": "file:lib/runtime-env-cra", "tss-react": "4.9.13" }, From b0da37886dc4faa2de56b967b92c91a5227b2a6c Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Sat, 12 Oct 2024 08:47:00 +0100 Subject: [PATCH 38/44] feat: authorization groups creatable and editable by internal users (#2035) * feat: authorization_groups creatable and editable by internal users * chore: edit button on show authorization group page * chore: documentation * chore: isort --- .../application/access_control/api/filters.py | 39 +++- .../access_control/api/permissions.py | 51 ++++++ .../access_control/api/serializers.py | 74 +++++++- .../application/access_control/api/views.py | 69 ++----- ...010_authorization_group_member_and_more.py | 72 ++++++++ backend/application/access_control/models.py | 23 ++- .../queries/authorization_group.py | 9 - .../queries/authorization_group_member.py | 41 +++++ backend/application/access_control/signals.py | 17 +- backend/config/api_router.py | 6 + ...thorization_authorization_group_members.py | 168 ++++++++++++++++++ ...test_authorization_authorization_groups.py | 118 ++++++------ .../api/test_authorization_users.py | 8 +- .../access_control/api/test_serializers.py | 91 ++++++++++ .../services/test_authorization.py | 45 ++++- backend/unittests/base_test_case.py | 11 +- .../fixtures/unittests_fixtures.json | 27 ++- docs/usage/users_permissions.md | 5 +- .../AccessControlAdministration.tsx | 2 +- .../AuthorizationGroupMemberAdd.tsx} | 23 ++- .../AuthorizationGroupMemberEdit.tsx | 96 ++++++++++ .../AuthorizationGroupMemberEmbeddedList.tsx | 100 +++++++++++ .../AuthorizationGroupMemberRemove.tsx} | 23 +-- .../AuthorizationGroupEmbeddedList.tsx | 19 +- .../AuthorizationGroupShow.tsx | 19 +- .../users/UserAGEmbeddedList.tsx | 92 ---------- .../src/access_control/users/UserShow.tsx | 21 +-- frontend/src/commons/functions.tsx | 5 + .../product_members/ProductMemberEdit.tsx | 1 + 29 files changed, 985 insertions(+), 290 deletions(-) create mode 100644 backend/application/access_control/migrations/0010_authorization_group_member_and_more.py create mode 100644 backend/application/access_control/queries/authorization_group_member.py create mode 100644 backend/unittests/access_control/api/test_authorization_authorization_group_members.py create mode 100644 backend/unittests/access_control/api/test_serializers.py rename frontend/src/access_control/{authorization_groups/AuthorizationGroupUserAdd.tsx => authorization_group_members/AuthorizationGroupMemberAdd.tsx} (84%) create mode 100644 frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEdit.tsx create mode 100644 frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEmbeddedList.tsx rename frontend/src/access_control/{authorization_groups/AuthorizationGroupUserRemove.tsx => authorization_group_members/AuthorizationGroupMemberRemove.tsx} (64%) delete mode 100644 frontend/src/access_control/users/UserAGEmbeddedList.tsx diff --git a/backend/application/access_control/api/filters.py b/backend/application/access_control/api/filters.py index 468d5cf87..105ed95b1 100644 --- a/backend/application/access_control/api/filters.py +++ b/backend/application/access_control/api/filters.py @@ -1,6 +1,12 @@ +from django.db.models import Exists from django_filters import CharFilter, FilterSet, NumberFilter, OrderingFilter -from application.access_control.models import API_Token, Authorization_Group, User +from application.access_control.models import ( + API_Token, + Authorization_Group, + Authorization_Group_Member, + User, +) class UserFilter(FilterSet): @@ -53,6 +59,7 @@ def __init__(self, data=None, queryset=None, *, request=None, prefix=None): class AuthorizationGroupFilter(FilterSet): name = CharFilter(field_name="name", lookup_expr="icontains") oidc_group = CharFilter(field_name="oidc_group", lookup_expr="icontains") + user = NumberFilter(field_name="users") # search is needed for the ReferenceArrayInput field of react-admin search = CharFilter(field_name="name", lookup_expr="icontains") @@ -66,6 +73,36 @@ class Meta: model = Authorization_Group fields = ["name", "oidc_group", "search"] + def get_user(self, queryset, name, value): # pylint: disable=unused-argument + # field_name is used as a positional argument + + authorization_group_members = Authorization_Group_Member.objects.filter( + user__id=value + ) + queryset = queryset.annotate( + member=Exists(authorization_group_members), + ) + return queryset.filter(member=True) + + +class AuthorizationGroupMemberFilter(FilterSet): + username = CharFilter(field_name="user__username", lookup_expr="icontains") + full_name = CharFilter(field_name="user__full_name", lookup_expr="icontains") + + ordering = OrderingFilter( + # tuple-mapping retains order + fields=( + ("user__full_name", "user_data.full_name"), + ("authorization_group", "authorization_group"), + ("user", "user"), + ("is_manager", "is_manager"), + ), + ) + + class Meta: + model = Authorization_Group_Member + fields = ["authorization_group", "user", "is_manager", "username", "full_name"] + class ApiTokenFilter(FilterSet): name = CharFilter(field_name="user__username", lookup_expr="icontains") diff --git a/backend/application/access_control/api/permissions.py b/backend/application/access_control/api/permissions.py index cda535394..580a9ae93 100644 --- a/backend/application/access_control/api/permissions.py +++ b/backend/application/access_control/api/permissions.py @@ -1,5 +1,11 @@ +from django.shortcuts import get_object_or_404 from rest_framework.permissions import BasePermission +from application.access_control.models import ( + Authorization_Group, + Authorization_Group_Member, +) + class UserHasSuperuserPermission(BasePermission): def has_permission(self, request, view): @@ -20,3 +26,48 @@ def has_object_permission(self, request, view, obj): return request.user.is_superuser return True + + +class UserHasAuthorizationGroupPermission(BasePermission): + def has_permission(self, request, view): + if request.method == "POST": + return not request.user.is_external + + return True + + def has_object_permission(self, request, view, obj: Authorization_Group): + if request.method != "GET": + return _has_manage_permission(request, obj) + + return True + + +class UserHasAuthorizationGroupMemberPermission(BasePermission): + def has_permission(self, request, view): + if request.method == "POST": + authorization_group = get_object_or_404( + Authorization_Group, pk=request.data.get("authorization_group") + ) + return _has_manage_permission(request, authorization_group) + + return True + + def has_object_permission(self, request, view, obj: Authorization_Group_Member): + if request.method != "GET": + return _has_manage_permission(request, obj.authorization_group) + + return True + + +def _has_manage_permission(request, authorization_group: Authorization_Group) -> bool: + user = request.user + if user and user.is_superuser: + return True + + try: + authorization_group_member = Authorization_Group_Member.objects.get( + authorization_group=authorization_group, user=user + ) + return authorization_group_member.is_manager + except Authorization_Group_Member.DoesNotExist: + return False diff --git a/backend/application/access_control/api/serializers.py b/backend/application/access_control/api/serializers.py index b71a4de84..43d7bebb0 100644 --- a/backend/application/access_control/api/serializers.py +++ b/backend/application/access_control/api/serializers.py @@ -8,9 +8,18 @@ ModelSerializer, Serializer, SerializerMethodField, + ValidationError, ) -from application.access_control.models import API_Token, Authorization_Group, User +from application.access_control.models import ( + API_Token, + Authorization_Group, + Authorization_Group_Member, + User, +) +from application.access_control.queries.authorization_group_member import ( + get_authorization_group_member, +) from application.access_control.services.authorization import get_user_permissions from application.access_control.services.roles_permissions import Permissions, Roles from application.commons.services.global_request import get_current_user @@ -92,7 +101,7 @@ def get_has_password(self, obj: User) -> bool: class UserSerializer(UserListSerializer): full_name = SerializerMethodField() - authorization_groups = NestedAuthorizationGroupSerializer(many=True) + has_authorization_groups = SerializerMethodField() has_product_group_members = SerializerMethodField() has_product_members = SerializerMethodField() @@ -116,7 +125,7 @@ class Meta: "is_oidc_user", "date_joined", "has_password", - "authorization_groups", + "has_authorization_groups", "has_product_group_members", "has_product_members", ] @@ -126,7 +135,7 @@ def to_representation(self, instance: User): user = get_current_user() if user and not user.is_superuser and not user.pk == instance.pk: - data.pop("authorization_groups") + data.pop("has_authorization_groups") data.pop("has_product_group_members") data.pop("has_product_members") @@ -135,6 +144,9 @@ def to_representation(self, instance: User): def get_full_name(self, obj: User) -> str: return obj.full_name + def get_has_authorization_groups(self, obj: User) -> bool: + return Authorization_Group_Member.objects.filter(user=obj).exists() + def get_has_product_group_members(self, obj: User) -> bool: return Product_Member.objects.filter( user=obj, product__is_product_group=True @@ -175,10 +187,11 @@ class UserPasswortRulesSerializer(Serializer): class AuthorizationGroupSerializer(ModelSerializer): has_product_group_members = SerializerMethodField() has_product_members = SerializerMethodField() + is_manager = SerializerMethodField() class Meta: model = Authorization_Group - fields = "__all__" + exclude = ["users"] def get_has_product_group_members(self, obj: Authorization_Group) -> bool: return Product_Authorization_Group_Member.objects.filter( @@ -190,9 +203,56 @@ def get_has_product_members(self, obj: Authorization_Group) -> bool: authorization_group=obj, product__is_product_group=False ).exists() + def get_is_manager(self, obj: Authorization_Group) -> bool: + user = get_current_user() + return Authorization_Group_Member.objects.filter( + authorization_group=obj, user=user, is_manager=True + ).exists() + + +class AuthorizationGroupListSerializer(ModelSerializer): + class Meta: + model = Authorization_Group + exclude = ["users"] + + +class AuthorizationGroupMemberSerializer(ModelSerializer): + authorization_group_data = AuthorizationGroupListSerializer( + source="authorization_group", + read_only=True, + ) + user_data = UserListSerializer(source="user", read_only=True) -class AuthorizationGroupUserSerializer(Serializer): - user = IntegerField(validators=[MinValueValidator(0)]) + class Meta: + model = Authorization_Group_Member + fields = "__all__" + + def validate(self, attrs: dict): + self.instance: Authorization_Group_Member + data_authorization_group: Optional[Authorization_Group] = attrs.get( + "authorization_group" + ) + data_user = attrs.get("user") + + if self.instance is not None and ( + ( + data_authorization_group + and data_authorization_group != self.instance.authorization_group + ) + or (data_user and data_user != self.instance.user) + ): + raise ValidationError("Authorization group and user cannot be changed") + + if self.instance is None: + authorization_group_member = get_authorization_group_member( + data_authorization_group, data_user + ) + if authorization_group_member: + raise ValidationError( + f"Authorization group member {data_authorization_group} / {data_user} already exists" + ) + + return attrs class UserSettingsSerializer(ModelSerializer): diff --git a/backend/application/access_control/api/views.py b/backend/application/access_control/api/views.py index 961baf61b..cba21616a 100644 --- a/backend/application/access_control/api/views.py +++ b/backend/application/access_control/api/views.py @@ -20,15 +20,20 @@ from application.access_control.api.filters import ( ApiTokenFilter, AuthorizationGroupFilter, + AuthorizationGroupMemberFilter, UserFilter, ) -from application.access_control.api.permissions import UserHasSuperuserPermission +from application.access_control.api.permissions import ( + UserHasAuthorizationGroupMemberPermission, + UserHasAuthorizationGroupPermission, + UserHasSuperuserPermission, +) from application.access_control.api.serializers import ( ApiTokenSerializer, AuthenticationRequestSerializer, AuthenticationResponseSerializer, + AuthorizationGroupMemberSerializer, AuthorizationGroupSerializer, - AuthorizationGroupUserSerializer, CreateApiTokenResponseSerializer, ProductApiTokenSerializer, UserListSerializer, @@ -41,15 +46,17 @@ from application.access_control.models import ( API_Token, Authorization_Group, + Authorization_Group_Member, JWT_Secret, User, ) from application.access_control.queries.authorization_group import ( - get_authorization_group_by_id, get_authorization_groups, ) +from application.access_control.queries.authorization_group_member import ( + get_authorization_group_members, +) from application.access_control.queries.user import ( - get_user_by_id, get_users, get_users_without_api_tokens, ) @@ -201,58 +208,20 @@ class AuthorizationGroupViewSet(ModelViewSet): serializer_class = AuthorizationGroupSerializer filterset_class = AuthorizationGroupFilter queryset = Authorization_Group.objects.none() - permission_classes = (IsAuthenticated, UserHasSuperuserPermission) + permission_classes = (IsAuthenticated, UserHasAuthorizationGroupPermission) def get_queryset(self): return get_authorization_groups() - @extend_schema( - methods=["POST"], - request=AuthorizationGroupUserSerializer, - responses={status.HTTP_204_NO_CONTENT: None}, - ) - @action(detail=True, methods=["post"]) - def add_user(self, request, pk=None): - request_serializer = AuthorizationGroupUserSerializer(data=request.data) - if not request_serializer.is_valid(): - raise ValidationError(request_serializer.errors) - - user_id = request_serializer.validated_data.get("user") - authorization_group = get_authorization_group_by_id(pk) - if not authorization_group: - raise ValidationError(f"Authorization group {pk} does not exist") - user = get_user_by_id(user_id) - if not user: - raise ValidationError(f"User {user_id} does not exist") - - authorization_group.users.add(user) - - return Response(status=status.HTTP_204_NO_CONTENT) +class AuthorizationGroupMemberViewSet(ModelViewSet): + serializer_class = AuthorizationGroupMemberSerializer + filterset_class = AuthorizationGroupMemberFilter + queryset = Authorization_Group_Member.objects.none() + permission_classes = (IsAuthenticated, UserHasAuthorizationGroupMemberPermission) - @extend_schema( - methods=["POST"], - request=AuthorizationGroupUserSerializer, - responses={status.HTTP_204_NO_CONTENT: None}, - ) - @action(detail=True, methods=["post"]) - def remove_user(self, request, pk=None): - request_serializer = AuthorizationGroupUserSerializer(data=request.data) - if not request_serializer.is_valid(): - raise ValidationError(request_serializer.errors) - - user_id = request_serializer.validated_data.get("user") - - authorization_group = get_authorization_group_by_id(pk) - if not authorization_group: - raise ValidationError(f"Authorization group {pk} does not exist") - user = get_user_by_id(user_id) - if not user: - raise ValidationError(f"User {user_id} does not exist") - - authorization_group.users.remove(user) - - return Response(status=status.HTTP_204_NO_CONTENT) + def get_queryset(self): + return get_authorization_group_members() class ApiTokenViewSet(ListModelMixin, GenericViewSet): diff --git a/backend/application/access_control/migrations/0010_authorization_group_member_and_more.py b/backend/application/access_control/migrations/0010_authorization_group_member_and_more.py new file mode 100644 index 000000000..2fef4170c --- /dev/null +++ b/backend/application/access_control/migrations/0010_authorization_group_member_and_more.py @@ -0,0 +1,72 @@ +# Generated by Django 5.1.2 on 2024-10-10 11:56 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("access_control", "0009_user_is_oidc_user"), + ] + + operations = [ + migrations.SeparateDatabaseAndState( + database_operations=[ + migrations.RunSQL( + sql="ALTER TABLE access_control_authorization_group_users RENAME TO access_control_authorization_group_member", + reverse_sql="ALTER TABLE access_control_authorization_group_member RENAME TO access_control_authorization_group_users", + ), + ], + state_operations=[ + migrations.CreateModel( + name="Authorization_Group_Member", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("is_manager", models.BooleanField(default=False)), + ( + "authorization_group", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="access_control.authorization_group", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "unique_together": {("authorization_group", "user")}, + }, + ), + migrations.AlterField( + model_name="authorization_group", + name="users", + field=models.ManyToManyField( + blank=True, + related_name="authorization_groups", + through="access_control.Authorization_Group_Member", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.AddField( + model_name="authorization_group_member", + name="is_manager", + field=models.BooleanField(default=False), + ), + ] diff --git a/backend/application/access_control/models.py b/backend/application/access_control/models.py index cde118e04..c983fa158 100644 --- a/backend/application/access_control/models.py +++ b/backend/application/access_control/models.py @@ -3,6 +3,7 @@ CASCADE, BooleanField, CharField, + ForeignKey, Index, ManyToManyField, Model, @@ -55,7 +56,12 @@ def save(self, *args, **kwargs): class Authorization_Group(Model): name = CharField(max_length=255, unique=True) oidc_group = CharField(max_length=255, blank=True) - users = ManyToManyField(User, related_name="authorization_groups", blank=True) + users: ManyToManyField = ManyToManyField( + User, + through="Authorization_Group_Member", + related_name="authorization_groups", + blank=True, + ) class Meta: verbose_name = "Authorization Group" @@ -68,6 +74,21 @@ def __str__(self): return self.name +class Authorization_Group_Member(Model): + authorization_group = ForeignKey(Authorization_Group, on_delete=CASCADE) + user = ForeignKey(User, on_delete=CASCADE) + is_manager = BooleanField(default=False) + + class Meta: + unique_together = ( + "authorization_group", + "user", + ) + + def __str__(self): + return f"{self.authorization_group} / {self.user}" + + class JWT_Secret(Model): secret = EncryptedCharField(max_length=255) diff --git a/backend/application/access_control/queries/authorization_group.py b/backend/application/access_control/queries/authorization_group.py index d8066f6f4..b66f1f982 100644 --- a/backend/application/access_control/queries/authorization_group.py +++ b/backend/application/access_control/queries/authorization_group.py @@ -1,18 +1,9 @@ -from typing import Optional - from django.db.models.query import QuerySet from application.access_control.models import Authorization_Group from application.commons.services.global_request import get_current_user -def get_authorization_group_by_id(pk: int) -> Optional[Authorization_Group]: - try: - return Authorization_Group.objects.get(pk=pk) - except Authorization_Group.DoesNotExist: - return None - - def get_authorization_groups() -> QuerySet[Authorization_Group]: user = get_current_user() diff --git a/backend/application/access_control/queries/authorization_group_member.py b/backend/application/access_control/queries/authorization_group_member.py new file mode 100644 index 000000000..e4ee4afed --- /dev/null +++ b/backend/application/access_control/queries/authorization_group_member.py @@ -0,0 +1,41 @@ +from typing import Optional + +from django.db.models.query import QuerySet + +from application.access_control.models import ( + Authorization_Group, + Authorization_Group_Member, + User, +) +from application.access_control.queries.authorization_group import ( + get_authorization_groups, +) +from application.commons.services.global_request import get_current_user + + +def get_authorization_group_member( + authorization_group: Authorization_Group, user: User +) -> Optional[Authorization_Group_Member]: + try: + return Authorization_Group_Member.objects.get( + authorization_group=authorization_group, user=user + ) + except Authorization_Group_Member.DoesNotExist: + return None + + +def get_authorization_group_members() -> QuerySet[Authorization_Group_Member]: + user = get_current_user() + + if user is None: + return Authorization_Group_Member.objects.none() + + authorization_group_members = Authorization_Group_Member.objects.all() + + if user.is_superuser: + return authorization_group_members + + authorization_groups = get_authorization_groups() + return authorization_group_members.filter( + authorization_group__in=authorization_groups + ) diff --git a/backend/application/access_control/signals.py b/backend/application/access_control/signals.py index 8c5e0fe02..d9bef9ffc 100644 --- a/backend/application/access_control/signals.py +++ b/backend/application/access_control/signals.py @@ -8,7 +8,12 @@ from django.db.models.signals import post_delete, post_save from django.dispatch import receiver -from application.access_control.models import Authorization_Group, User +from application.access_control.models import ( + Authorization_Group, + Authorization_Group_Member, + User, +) +from application.commons.services.global_request import get_current_user from application.commons.services.log_message import format_log_message logger = logging.getLogger("secobserve.access_control") @@ -41,15 +46,21 @@ def signal_user_login_failed( # pylint: disable=unused-argument @receiver(post_save, sender=Authorization_Group) -def branch_post_save( # pylint: disable=unused-argument +def authorization_group_post_save( # pylint: disable=unused-argument sender, instance: Authorization_Group, created: bool, **kwargs ) -> None: # sender is needed according to Django documentation _invalidate_oidc_groups_hashes() + if created: + user = get_current_user() + if user and not user.is_superuser: + Authorization_Group_Member.objects.create( + authorization_group=instance, user=user, is_manager=True + ) @receiver(post_delete, sender=Authorization_Group) -def branch_post_delete( # pylint: disable=unused-argument +def authorization_group_post_delete( # pylint: disable=unused-argument sender, instance: Authorization_Group, **kwargs ) -> None: # sender is needed according to Django documentation diff --git a/backend/config/api_router.py b/backend/config/api_router.py index 07a790bdc..737fa35e3 100644 --- a/backend/config/api_router.py +++ b/backend/config/api_router.py @@ -2,6 +2,7 @@ from application.access_control.api.views import ( ApiTokenViewSet, + AuthorizationGroupMemberViewSet, AuthorizationGroupViewSet, ProductApiTokenViewset, UserViewSet, @@ -43,6 +44,11 @@ router.register( "authorization_groups", AuthorizationGroupViewSet, basename="authorization_groups" ) +router.register( + "authorization_group_members", + AuthorizationGroupMemberViewSet, + basename="authorization_group_members", +) router.register("api_tokens", ApiTokenViewSet, basename="api_tokens") router.register( "product_api_tokens", ProductApiTokenViewset, basename="product_api_tokens" diff --git a/backend/unittests/access_control/api/test_authorization_authorization_group_members.py b/backend/unittests/access_control/api/test_authorization_authorization_group_members.py new file mode 100644 index 000000000..f3b41d4c3 --- /dev/null +++ b/backend/unittests/access_control/api/test_authorization_authorization_group_members.py @@ -0,0 +1,168 @@ +from unittests.access_control.api.test_authorization import ( + APITest, + TestAuthorizationBase, +) + + +class TestAuthorizationAuthorizationGroupMembers(TestAuthorizationBase): + def test_authorization_authorization_group_members(self): + expected_data = "{'count': 2, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'is_manager': True, 'authorization_group': 3, 'user': 2}, {'id': 2, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 3, 'username': 'db_internal_read', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_read', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:25:06+01:00', 'has_password': False}, 'is_manager': False, 'authorization_group': 3, 'user': 3}]}" + self._test_api( + APITest( + "db_admin", + "get", + "/api/authorization_group_members/", + None, + 200, + expected_data, + ) + ) + + expected_data = "{'count': 2, 'next': None, 'previous': None, 'results': [{'id': 1, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'is_manager': True, 'authorization_group': 3, 'user': 2}, {'id': 2, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 3, 'username': 'db_internal_read', 'full_name': 'db_internal_read'}, 'is_manager': False, 'authorization_group': 3, 'user': 3}]}" + self._test_api( + APITest( + "db_internal_write", + "get", + "/api/authorization_group_members/", + None, + 200, + expected_data, + no_second_user=True, + ) + ) + + expected_data = "{'count': 0, 'next': None, 'previous': None, 'results': []}" + self._test_api( + APITest( + "db_product_group_user", + "get", + "/api/authorization_group_members/", + None, + 200, + expected_data, + no_second_user=True, + ) + ) + expected_data = "{'id': 1, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False}, 'is_manager': True, 'authorization_group': 3, 'user': 2}" + self._test_api( + APITest( + username="db_internal_write", + method="get", + url="/api/authorization_group_members/1/", + post_data=None, + expected_status_code=200, + expected_data=expected_data, + no_second_user=True, + ) + ) + + expected_data = ( + "{'message': 'No Authorization_Group_Member matches the given query.'}" + ) + self._test_api( + APITest( + "db_product_group_user", + "get", + "/api/authorization_group_members/1/", + None, + 404, + expected_data, + no_second_user=True, + ) + ) + + self._test_api( + APITest( + "db_internal_write", + "get", + "/api/authorization_group_members/99999/", + None, + 404, + expected_data, + no_second_user=True, + ) + ) + + post_data = {"authorization_group": 3, "user": 1, "is_manager": False} + expected_data = ( + "{'message': 'You do not have permission to perform this action.'}" + ) + self._test_api( + APITest( + "db_internal_read", + "post", + "/api/authorization_group_members/", + post_data, + 403, + expected_data, + no_second_user=True, + ) + ) + expected_data = "{'id': 3, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 1, 'username': 'db_admin', 'full_name': 'db_admin'}, 'is_manager': False, 'authorization_group': 3, 'user': 1}" + self._test_api( + APITest( + "db_internal_write", + "post", + "/api/authorization_group_members/", + post_data, + 201, + expected_data, + no_second_user=True, + ) + ) + + post_data = {"is_manager": True} + expected_data = ( + "{'message': 'You do not have permission to perform this action.'}" + ) + self._test_api( + APITest( + "db_internal_read", + "patch", + "/api/authorization_group_members/3/", + post_data, + 403, + expected_data, + no_second_user=True, + ) + ) + + expected_data = "{'id': 3, 'authorization_group_data': {'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}, 'user_data': {'id': 1, 'username': 'db_admin', 'full_name': 'db_admin'}, 'is_manager': True, 'authorization_group': 3, 'user': 1}" + self._test_api( + APITest( + "db_internal_write", + "patch", + "/api/authorization_group_members/3/", + post_data, + 200, + expected_data, + no_second_user=True, + ) + ) + + expected_data = ( + "{'message': 'You do not have permission to perform this action.'}" + ) + self._test_api( + APITest( + "db_internal_read", + "delete", + "/api/authorization_group_members/3/", + None, + 403, + expected_data, + no_second_user=True, + ) + ) + expected_data = "None" + self._test_api( + APITest( + "db_internal_write", + "delete", + "/api/authorization_group_members/3/", + None, + 204, + expected_data, + no_second_user=True, + ) + ) diff --git a/backend/unittests/access_control/api/test_authorization_authorization_groups.py b/backend/unittests/access_control/api/test_authorization_authorization_groups.py index 85dbd7de4..c19e32958 100644 --- a/backend/unittests/access_control/api/test_authorization_authorization_groups.py +++ b/backend/unittests/access_control/api/test_authorization_authorization_groups.py @@ -1,3 +1,8 @@ +from application.access_control.models import ( + Authorization_Group, + Authorization_Group_Member, + User, +) from unittests.access_control.api.test_authorization import ( APITest, TestAuthorizationBase, @@ -11,7 +16,7 @@ class TestAuthorizationAuthorizationGroups(TestAuthorizationBase): def test_authorization_authorization_groups(self): prepare_authorization_groups() - expected_data = "{'count': 5, 'next': None, 'previous': None, 'results': [{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}, {'id': 5, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_read', 'oidc_group': '', 'users': [3]}, {'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}, {'id': 7, 'has_product_group_members': True, 'has_product_members': False, 'name': 'db_group_product_group', 'oidc_group': '', 'users': [6]}, {'id': 8, 'has_product_group_members': False, 'has_product_members': False, 'name': 'db_group_unused', 'oidc_group': '', 'users': []}]}" + expected_data = "{'count': 5, 'next': None, 'previous': None, 'results': [{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': False, 'name': 'db_group_internal_write', 'oidc_group': ''}, {'id': 5, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': False, 'name': 'db_group_internal_read', 'oidc_group': ''}, {'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': False, 'name': 'db_group_external', 'oidc_group': ''}, {'id': 7, 'has_product_group_members': True, 'has_product_members': False, 'is_manager': False, 'name': 'db_group_product_group', 'oidc_group': ''}, {'id': 8, 'has_product_group_members': False, 'has_product_members': False, 'is_manager': False, 'name': 'db_group_unused', 'oidc_group': ''}]}" self._test_api( APITest( "db_admin", @@ -23,8 +28,8 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}]}" - expected_data_product_group = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 7, 'has_product_group_members': True, 'has_product_members': False, 'name': 'db_group_product_group', 'oidc_group': '', 'users': [6]}]}" + expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': True, 'name': 'db_group_internal_write', 'oidc_group': ''}]}" + expected_data_product_group = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 7, 'has_product_group_members': True, 'has_product_members': False, 'is_manager': False, 'name': 'db_group_product_group', 'oidc_group': ''}]}" self._test_api( APITest( "db_internal_write", @@ -36,7 +41,7 @@ def test_authorization_authorization_groups(self): expected_data_product_group=expected_data_product_group, ) ) - expected_data = "{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_internal_write', 'oidc_group': '', 'users': [2]}" + expected_data = "{'id': 4, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': True, 'name': 'db_group_internal_write', 'oidc_group': ''}" self._test_api( APITest( "db_internal_write", @@ -60,7 +65,7 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}]}" + expected_data = "{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': False, 'name': 'db_group_external', 'oidc_group': ''}]}" self._test_api( APITest( "db_external", @@ -71,7 +76,7 @@ def test_authorization_authorization_groups(self): expected_data, ) ) - expected_data = "{'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'name': 'db_group_external', 'oidc_group': '', 'users': [4]}" + expected_data = "{'id': 6, 'has_product_group_members': False, 'has_product_members': True, 'is_manager': False, 'name': 'db_group_external', 'oidc_group': ''}" self._test_api( APITest( "db_external", @@ -94,7 +99,7 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = "{'id': 9, 'has_product_group_members': False, 'has_product_members': False, 'name': 'string', 'oidc_group': 'oidc', 'users': []}" + expected_data = "{'id': 9, 'has_product_group_members': False, 'has_product_members': False, 'is_manager': False, 'name': 'string', 'oidc_group': 'oidc'}" self._test_api( APITest( "db_admin", @@ -110,32 +115,17 @@ def test_authorization_authorization_groups(self): ) ) - expected_data = ( - "{'message': 'You do not have permission to perform this action.'}" - ) + expected_data = "{'id': 10, 'has_product_group_members': False, 'has_product_members': False, 'is_manager': True, 'name': 'string_2', 'oidc_group': 'oidc'}" self._test_api( APITest( "db_internal_write", "post", "/api/authorization_groups/", { - "name": "string", + "name": "string_2", "oidc_group": "oidc", }, - 403, - expected_data, - no_second_user=True, - ) - ) - - expected_data = "{'id': 9, 'has_product_group_members': False, 'has_product_members': False, 'name': 'changed_string', 'oidc_group': 'oidc', 'users': []}" - self._test_api( - APITest( - "db_admin", - "patch", - "/api/authorization_groups/9/", - {"name": "changed_string"}, - 200, + 201, expected_data, no_second_user=True, ) @@ -146,86 +136,88 @@ def test_authorization_authorization_groups(self): ) self._test_api( APITest( - "db_internal_write", - "patch", - "/api/authorization_groups/9/", - {"name": "changed_string"}, + "db_external", + "post", + "/api/authorization_groups/", + { + "name": "string_3", + "oidc_group": "oidc", + }, 403, expected_data, no_second_user=True, ) ) + expected_data = "{'id': 9, 'has_product_group_members': False, 'has_product_members': False, 'is_manager': False, 'name': 'changed_string', 'oidc_group': 'oidc'}" self._test_api( APITest( - "db_internal_write", - "delete", + "db_admin", + "patch", "/api/authorization_groups/9/", - None, - 403, + {"name": "changed_string"}, + 200, expected_data, no_second_user=True, ) ) - post_data = {"user": 2} - + expected_data = "{'id': 10, 'has_product_group_members': False, 'has_product_members': False, 'is_manager': True, 'name': 'changed_string_2', 'oidc_group': 'oidc'}" self._test_api( APITest( "db_internal_write", - "post", - "/api/authorization_groups/9/add_user/", - post_data, - 403, - None, + "patch", + "/api/authorization_groups/10/", + {"name": "changed_string_2"}, + 200, + expected_data, no_second_user=True, ) ) - self._test_api( - APITest( - "db_admin", - "post", - "/api/authorization_groups/9/add_user/", - post_data, - 204, - None, - no_second_user=True, - ) + Authorization_Group_Member.objects.create( + authorization_group=Authorization_Group.objects.get(id=10), + user=User.objects.get(username="db_internal_read"), + is_manager=False, ) + expected_data = ( + "{'message': 'You do not have permission to perform this action.'}" + ) self._test_api( APITest( - "db_internal_write", - "post", - "/api/authorization_groups/9/remove_user/", - post_data, + "db_internal_read", + "patch", + "/api/authorization_groups/10/", + {"name": "changed_string_2"}, 403, - None, + expected_data, no_second_user=True, ) ) self._test_api( APITest( - "db_admin", - "post", - "/api/authorization_groups/9/remove_user/", - post_data, - 204, + "db_internal_read", + "delete", + "/api/authorization_groups/10/", None, + 403, + expected_data, no_second_user=True, ) ) + expected_data = None + self._test_api( APITest( - "db_admin", + "db_internal_write", "delete", - "/api/authorization_groups/9/", + "/api/authorization_groups/10/", None, 204, - None, + expected_data, no_second_user=True, ) ) diff --git a/backend/unittests/access_control/api/test_authorization_users.py b/backend/unittests/access_control/api/test_authorization_users.py index 383f4f156..7b5e4c5ac 100644 --- a/backend/unittests/access_control/api/test_authorization_users.py +++ b/backend/unittests/access_control/api/test_authorization_users.py @@ -33,7 +33,7 @@ def test_authorization_users(self): ) ) - expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}], 'has_product_group_members': False, 'has_product_members': True}" + expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'has_authorization_groups': True, 'has_product_group_members': False, 'has_product_members': True}" expected_data_product_group = "{'id': 2, 'username': 'db_internal_write', 'full_name': 'db_internal_write'}" self._test_api( APITest( @@ -64,7 +64,7 @@ def test_authorization_users(self): self._test_api( APITest("db_external", "get", "/api/users/", None, 200, expected_data) ) - expected_data = "{'id': 4, 'username': 'db_external', 'first_name': '', 'last_name': '', 'full_name': 'db_external', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': True, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-12T19:48:08.514000+01:00', 'has_password': False, 'authorization_groups': [], 'has_product_group_members': False, 'has_product_members': True}" + expected_data = "{'id': 4, 'username': 'db_external', 'first_name': '', 'last_name': '', 'full_name': 'db_external', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': True, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-12T19:48:08.514000+01:00', 'has_password': False, 'has_authorization_groups': False, 'has_product_group_members': False, 'has_product_members': True}" self._test_api( APITest("db_external", "get", "/api/users/4/", None, 200, expected_data) ) @@ -214,7 +214,7 @@ def test_authorization_users(self): ) ) - expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}], 'has_product_group_members': False, 'has_product_members': True}" + expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'light', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'has_authorization_groups': True, 'has_product_group_members': False, 'has_product_members': True}" self._test_api( APITest( "db_internal_write", @@ -228,7 +228,7 @@ def test_authorization_users(self): ) post_data = {"setting_theme": "dark"} - expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'dark', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'authorization_groups': [{'id': 3, 'name': 'non_oidc_group', 'oidc_group': ''}], 'has_product_group_members': False, 'has_product_members': True}" + expected_data = "{'id': 2, 'username': 'db_internal_write', 'first_name': '', 'last_name': '', 'full_name': 'db_internal_write', 'email': '', 'is_active': True, 'is_superuser': False, 'is_external': False, 'setting_theme': 'dark', 'setting_list_size': 'medium', 'permissions': [, ], 'setting_list_properties': '', 'oidc_groups_hash': '', 'is_oidc_user': False, 'date_joined': '2022-12-07T20:24:53+01:00', 'has_password': False, 'has_authorization_groups': True, 'has_product_group_members': False, 'has_product_members': True}" self._test_api( APITest( "db_internal_write", diff --git a/backend/unittests/access_control/api/test_serializers.py b/backend/unittests/access_control/api/test_serializers.py new file mode 100644 index 000000000..6bdb384be --- /dev/null +++ b/backend/unittests/access_control/api/test_serializers.py @@ -0,0 +1,91 @@ +from unittest.mock import patch + +from rest_framework.serializers import ValidationError + +from application.access_control.api.serializers import ( + AuthorizationGroupMemberSerializer, +) +from application.access_control.models import Authorization_Group +from unittests.base_test_case import BaseTestCase + + +class TestAuthorizationGroupMemberSerializer(BaseTestCase): + def test_validate_authorization_group_change(self): + auhorization_group_2 = Authorization_Group.objects.create(name="group_2") + authorization_group_member_serializer = AuthorizationGroupMemberSerializer( + self.authorization_group_member_1 + ) + attrs = { + "authorization_group": auhorization_group_2, + } + + with self.assertRaises(ValidationError) as e: + authorization_group_member_serializer.validate(attrs) + + self.assertEqual( + "[ErrorDetail(string='Authorization group and user cannot be changed', code='invalid')]", + str(e.exception), + ) + + def test_validate_user_change(self): + authorization_group_member_serializer = AuthorizationGroupMemberSerializer( + self.authorization_group_member_1 + ) + attrs = { + "user": self.user_external, + } + + with self.assertRaises(ValidationError) as e: + authorization_group_member_serializer.validate(attrs) + + self.assertEqual( + "[ErrorDetail(string='Authorization group and user cannot be changed', code='invalid')]", + str(e.exception), + ) + + @patch("application.access_control.api.serializers.get_authorization_group_member") + def test_validate_already_exists(self, mock_authorization_group_member): + mock_authorization_group_member.return_value = self.authorization_group_member_1 + authorization_group_member_serializer = AuthorizationGroupMemberSerializer() + attrs = { + "authorization_group": self.authorization_group_1, + "user": self.user_internal, + } + + with self.assertRaises(ValidationError) as e: + authorization_group_member_serializer.validate(attrs) + + self.assertEqual( + "[ErrorDetail(string='Authorization group member authorization_group_1 / user_internal@example.com already exists', code='invalid')]", + str(e.exception), + ) + mock_authorization_group_member.assert_called_with( + self.authorization_group_1, self.user_internal + ) + + def test_validate_successful_with_instance(self): + authorization_group_member_serializer = AuthorizationGroupMemberSerializer( + self.authorization_group_member_1 + ) + attrs = {"is_manager": False} + + new_attrs = authorization_group_member_serializer.validate(attrs) + + self.assertEqual(new_attrs, attrs) + + @patch("application.access_control.api.serializers.get_authorization_group_member") + def test_validate_successful_no_instance(self, mock_authorization_group_member): + mock_authorization_group_member.return_value = None + authorization_group_member_serializer = AuthorizationGroupMemberSerializer() + attrs = { + "authorization_group": self.authorization_group_1, + "user": self.user_external, + "is_manager": False, + } + + new_attrs = authorization_group_member_serializer.validate(attrs) + + self.assertEqual(new_attrs, attrs) + mock_authorization_group_member.assert_called_with( + self.authorization_group_1, self.user_external + ) diff --git a/backend/unittests/access_control/services/test_authorization.py b/backend/unittests/access_control/services/test_authorization.py index 26ddf55ad..bb54adf7b 100644 --- a/backend/unittests/access_control/services/test_authorization.py +++ b/backend/unittests/access_control/services/test_authorization.py @@ -3,7 +3,11 @@ from django.core.management import call_command from rest_framework.exceptions import PermissionDenied -from application.access_control.models import Authorization_Group, User +from application.access_control.models import ( + Authorization_Group, + Authorization_Group_Member, + User, +) from application.access_control.services.authorization import ( NoAuthorizationImplementedError, PermissionDoesNotExistError, @@ -461,7 +465,14 @@ def prepare_authorization_groups(): group_internal_write = Authorization_Group.objects.create( name="db_group_internal_write" ) - group_internal_write.users.add(user_internal_write) + Authorization_Group_Member.objects.filter( + authorization_group=group_internal_write + ).delete() + Authorization_Group_Member.objects.create( + authorization_group=group_internal_write, + user=user_internal_write, + is_manager=True, + ) Product_Authorization_Group_Member.objects.create( product=product_internal, authorization_group=group_internal_write, role=5 ) @@ -469,13 +480,27 @@ def prepare_authorization_groups(): group_internal_read = Authorization_Group.objects.create( name="db_group_internal_read" ) - group_internal_read.users.add(User.objects.get(id=3)) + Authorization_Group_Member.objects.filter( + authorization_group=group_internal_read + ).delete() + Authorization_Group_Member.objects.create( + authorization_group=group_internal_read, + user=User.objects.get(id=3), + is_manager=False, + ) Product_Authorization_Group_Member.objects.create( product=product_internal, authorization_group=group_internal_read, role=1 ) group_external = Authorization_Group.objects.create(name="db_group_external") - group_external.users.add(User.objects.get(id=4)) + Authorization_Group_Member.objects.filter( + authorization_group=group_external + ).delete() + Authorization_Group_Member.objects.create( + authorization_group=group_external, + user=User.objects.get(id=4), + is_manager=False, + ) Product_Authorization_Group_Member.objects.create( product=product_external, authorization_group=group_external, role=5 ) @@ -483,9 +508,17 @@ def prepare_authorization_groups(): group_product_group = Authorization_Group.objects.create( name="db_group_product_group" ) - group_product_group.users.add(User.objects.get(id=6)) + Authorization_Group_Member.objects.filter( + authorization_group=group_product_group + ).delete() + Authorization_Group_Member.objects.create( + authorization_group=group_product_group, + user=User.objects.get(id=6), + is_manager=False, + ) Product_Authorization_Group_Member.objects.create( product=product_group, authorization_group=group_product_group, role=5 ) - group_product_group = Authorization_Group.objects.create(name="db_group_unused") + group_unused = Authorization_Group.objects.create(name="db_group_unused") + Authorization_Group_Member.objects.filter(authorization_group=group_unused).delete() diff --git a/backend/unittests/base_test_case.py b/backend/unittests/base_test_case.py index 818d76efa..db4719235 100644 --- a/backend/unittests/base_test_case.py +++ b/backend/unittests/base_test_case.py @@ -1,6 +1,10 @@ from django.test import TestCase -from application.access_control.models import Authorization_Group, User +from application.access_control.models import ( + Authorization_Group, + Authorization_Group_Member, + User, +) from application.access_control.services.roles_permissions import Roles from application.core.models import ( Branch, @@ -63,6 +67,11 @@ def setUp(self) -> None: ) self.authorization_group_1 = Authorization_Group(name="authorization_group_1") + self.authorization_group_member_1 = Authorization_Group_Member( + authorization_group=self.authorization_group_1, + user=self.user_internal, + is_manager=True, + ) self.product_authorization_group_member_1 = Product_Authorization_Group_Member( product=self.product_1, authorization_group=self.authorization_group_1, diff --git a/backend/unittests/fixtures/unittests_fixtures.json b/backend/unittests/fixtures/unittests_fixtures.json index d0f241d76..5e8541823 100644 --- a/backend/unittests/fixtures/unittests_fixtures.json +++ b/backend/unittests/fixtures/unittests_fixtures.json @@ -132,8 +132,7 @@ "pk": 1, "fields": { "name": "oidc_group_1", - "oidc_group": "oidc_1", - "users": [] + "oidc_group": "oidc_1" } }, { @@ -141,8 +140,7 @@ "pk": 2, "fields": { "name": "oidc_group_2", - "oidc_group": "oidc_2", - "users": [] + "oidc_group": "oidc_2" } }, { @@ -150,8 +148,25 @@ "pk": 3, "fields": { "name": "non_oidc_group", - "oidc_group": "", - "users": [2, 3] + "oidc_group": "" + } + }, + { + "model": "access_control.authorization_group_member", + "pk": 1, + "fields": { + "authorization_group": 3, + "user": 2, + "is_manager": true + } + }, + { + "model": "access_control.authorization_group_member", + "pk": 2, + "fields": { + "authorization_group": 3, + "user": 3, + "is_manager": false } }, { diff --git a/docs/usage/users_permissions.md b/docs/usage/users_permissions.md index 216929082..a7c948809 100644 --- a/docs/usage/users_permissions.md +++ b/docs/usage/users_permissions.md @@ -36,7 +36,8 @@ There are some general permissions based on the user's type: | Change own password ^1)^ | X | X | X | | Change all passwords ^1)^ | - | - | X | | Manage users | - | - | X | -| Manage authorization groups | - | - | X | +| Create authorization groups | X | - | X | +| Manage authorization groups | X ^2)^ | X ^2)^ | X | | | | | | | Import VEX documents | - | - | X | | Manage VEX counters | - | - | X | @@ -46,6 +47,8 @@ There are some general permissions based on the user's type: **^1)^** Not for OIDC users +**^2)^** Only if the user is a manager of the authorization group + ## Authorization groups diff --git a/frontend/src/access_control/access_control_administration/AccessControlAdministration.tsx b/frontend/src/access_control/access_control_administration/AccessControlAdministration.tsx index 2b7202816..98c355542 100644 --- a/frontend/src/access_control/access_control_administration/AccessControlAdministration.tsx +++ b/frontend/src/access_control/access_control_administration/AccessControlAdministration.tsx @@ -113,7 +113,7 @@ export default function AccessControlAdministration() { - + diff --git a/frontend/src/access_control/authorization_groups/AuthorizationGroupUserAdd.tsx b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberAdd.tsx similarity index 84% rename from frontend/src/access_control/authorization_groups/AuthorizationGroupUserAdd.tsx rename to frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberAdd.tsx index a0ed6eb28..330cf66df 100644 --- a/frontend/src/access_control/authorization_groups/AuthorizationGroupUserAdd.tsx +++ b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberAdd.tsx @@ -2,17 +2,26 @@ import AddIcon from "@mui/icons-material/Add"; import CancelIcon from "@mui/icons-material/Cancel"; import { Button, Dialog, DialogContent, DialogTitle } from "@mui/material"; import { Fragment, useState } from "react"; -import { CreateBase, ReferenceInput, SaveButton, SimpleForm, Toolbar, useNotify, useRefresh } from "react-admin"; +import { + BooleanInput, + CreateBase, + ReferenceInput, + SaveButton, + SimpleForm, + Toolbar, + useNotify, + useRefresh, +} from "react-admin"; import { validate_required } from "../../commons/custom_validators"; import { AutocompleteInputWide } from "../../commons/layout/themes"; import { httpClient } from "../../commons/ra-data-django-rest-framework"; -export type AuthorizationGroupUserAddProps = { +export type AuthorizationGroupMemberAddProps = { id: any; }; -const AuthorizationGroupUserAdd = ({ id }: AuthorizationGroupUserAddProps) => { +const AuthorizationGroupMemberAdd = ({ id }: AuthorizationGroupMemberAddProps) => { const [open, setOpen] = useState(false); const refresh = useRefresh(); const notify = useNotify(); @@ -47,10 +56,11 @@ const AuthorizationGroupUserAdd = ({ id }: AuthorizationGroupUserAddProps) => { ); const add_user = (data: any) => { - const url = window.__RUNTIME_CONFIG__.API_BASE_URL + "/authorization_groups/" + id + "/add_user/"; + const url = window.__RUNTIME_CONFIG__.API_BASE_URL + "/authorization_group_members/"; + const body = JSON.stringify({ authorization_group: id, ...data }); httpClient(url, { method: "POST", - body: JSON.stringify(data), + body: body, }) .then(() => { refresh(); @@ -86,6 +96,7 @@ const AuthorizationGroupUserAdd = ({ id }: AuthorizationGroupUserAddProps) => { > + @@ -94,4 +105,4 @@ const AuthorizationGroupUserAdd = ({ id }: AuthorizationGroupUserAddProps) => { ); }; -export default AuthorizationGroupUserAdd; +export default AuthorizationGroupMemberAdd; diff --git a/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEdit.tsx b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEdit.tsx new file mode 100644 index 000000000..5b0f82b66 --- /dev/null +++ b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEdit.tsx @@ -0,0 +1,96 @@ +import CancelIcon from "@mui/icons-material/Cancel"; +import EditIcon from "@mui/icons-material/Edit"; +import { Button, Dialog, DialogContent, DialogTitle } from "@mui/material"; +import { Fragment, useState } from "react"; +import { BooleanInput, SaveButton, SimpleForm, Toolbar, useNotify, useRefresh, useUpdate } from "react-admin"; + +import { TextInputWide } from "../../commons/layout/themes"; + +const ProductMemberEdit = () => { + const [open, setOpen] = useState(false); + const [update] = useUpdate(); + const refresh = useRefresh(); + const notify = useNotify(); + const handleOpen = () => setOpen(true); + const handleCancel = () => setOpen(false); + const handleClose = (event: object, reason: string) => { + if (reason && reason == "backdropClick") return; + setOpen(false); + }; + + const member_update = async (data: any) => { + const patch = { + is_manager: data.is_manager, + }; + + update( + "authorization_group_members", + + { + id: data.id, + data: patch, + }, + { + onSuccess: () => { + refresh(); + notify("User member updated", { + type: "success", + }); + }, + onError: (error: any) => { + notify(error.message, { + type: "warning", + }); + }, + } + ); + setOpen(false); + }; + + const CancelButton = () => ( + + ); + + const CustomToolbar = () => ( + + + + + ); + return ( + + + + Edit user + + }> + + + + + + + ); +}; + +export default ProductMemberEdit; diff --git a/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEmbeddedList.tsx b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEmbeddedList.tsx new file mode 100644 index 000000000..5f7708e56 --- /dev/null +++ b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberEmbeddedList.tsx @@ -0,0 +1,100 @@ +import { Stack } from "@mui/material"; +import { + BooleanField, + Datagrid, + FilterForm, + Identifier, + ListContextProvider, + NullableBooleanInput, + TextInput, + WithRecord, + useListController, +} from "react-admin"; + +import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; +import TextUrlField from "../../commons/custom_fields/TextUrlField"; +import { is_superuser } from "../../commons/functions"; +import { getSettingListSize } from "../../commons/user_settings/functions"; +import AuthorizationGroupMemberAdd from "./AuthorizationGroupMemberAdd"; +import AuthorizationGroupMemberEdit from "./AuthorizationGroupMemberEdit"; +import AuthorizationGroupMemberRemove from "./AuthorizationGroupMemberRemove"; + +function listFilters() { + return [ + , + , + , + ]; +} + +const showUser = (id: Identifier) => { + return "#/users/" + id + "/show"; +}; + +type AuthorizationGroupMemberEmbeddedListProps = { + authorization_group: any; +}; + +const AuthorizationGroupMemberEmbeddedList = ({ authorization_group }: AuthorizationGroupMemberEmbeddedListProps) => { + const listContext = useListController({ + filter: { authorization_group: Number(authorization_group.id) }, + perPage: 25, + resource: "authorization_group_members", + sort: { field: "user_data.full_name", order: "ASC" }, + filterDefaultValues: {}, + disableSyncWithLocation: false, + }); + + if (listContext.isLoading) { + return
Loading...
; + } + + return ( + +
+ {(is_superuser() || authorization_group.is_manager) && ( + + )} + + + ( + + )} + /> + ( + + )} + /> + + {(is_superuser() || authorization_group.is_manager) && ( + ( + + + + + )} + /> + )} + + +
+
+ ); +}; + +export default AuthorizationGroupMemberEmbeddedList; diff --git a/frontend/src/access_control/authorization_groups/AuthorizationGroupUserRemove.tsx b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberRemove.tsx similarity index 64% rename from frontend/src/access_control/authorization_groups/AuthorizationGroupUserRemove.tsx rename to frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberRemove.tsx index 3abb67429..623074200 100644 --- a/frontend/src/access_control/authorization_groups/AuthorizationGroupUserRemove.tsx +++ b/frontend/src/access_control/authorization_group_members/AuthorizationGroupMemberRemove.tsx @@ -4,12 +4,11 @@ import { Button, Confirm, useNotify, useRefresh } from "react-admin"; import { httpClient } from "../../commons/ra-data-django-rest-framework"; -type AuthorizationGroupUserRemoveProps = { - id: any; - user: any; +type AuthorizationGroupMemberRemoveProps = { + authorization_group_member: any; }; -const AuthorizationGroupUserRemove = ({ id, user }: AuthorizationGroupUserRemoveProps) => { +const AuthorizationGroupMemberRemove = ({ authorization_group_member }: AuthorizationGroupMemberRemoveProps) => { const [open, setOpen] = useState(false); const refresh = useRefresh(); const notify = useNotify(); @@ -17,11 +16,13 @@ const AuthorizationGroupUserRemove = ({ id, user }: AuthorizationGroupUserRemove const handleDialogClose = () => setOpen(false); const removeUser = async () => { - const url = window.__RUNTIME_CONFIG__.API_BASE_URL + "/authorization_groups/" + id + "/remove_user/"; - const data = { user: user.id }; + const url = + window.__RUNTIME_CONFIG__.API_BASE_URL + + "/authorization_group_members/" + + authorization_group_member.id + + "/"; httpClient(url, { - method: "POST", - body: JSON.stringify(data), + method: "DELETE", }) .then(() => { refresh(); @@ -40,7 +41,9 @@ const AuthorizationGroupUserRemove = ({ id, user }: AuthorizationGroupUserRemove @@ -48,4 +51,4 @@ const AuthorizationGroupUserRemove = ({ id, user }: AuthorizationGroupUserRemove ); }; -export default AuthorizationGroupUserRemove; +export default AuthorizationGroupMemberRemove; diff --git a/frontend/src/access_control/authorization_groups/AuthorizationGroupEmbeddedList.tsx b/frontend/src/access_control/authorization_groups/AuthorizationGroupEmbeddedList.tsx index daea45a96..81afff920 100644 --- a/frontend/src/access_control/authorization_groups/AuthorizationGroupEmbeddedList.tsx +++ b/frontend/src/access_control/authorization_groups/AuthorizationGroupEmbeddedList.tsx @@ -1,7 +1,7 @@ import { Datagrid, FilterForm, ListContextProvider, TextField, TextInput, useListController } from "react-admin"; import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; -import { is_superuser } from "../../commons/functions"; +import { is_external } from "../../commons/functions"; import { getSettingListSize } from "../../commons/user_settings/functions"; import AuthorizationGroupCreateButton from "./AuthorizationGroupCreateButton"; @@ -13,15 +13,22 @@ function listFilters() { return [, ]; } -const AuthorizationGroupEmbeddedList = () => { +type AuthorizationGroupEmbeddedListProps = { + user: any; +}; + +const AuthorizationGroupEmbeddedList = ({ user }: AuthorizationGroupEmbeddedListProps) => { + const filter = user ? { user: Number(user.id) } : {}; + const storeKey = user ? false : "authorization_groups.embedded"; + const listContext = useListController({ - filter: {}, + filter: filter, perPage: 25, resource: "authorization_groups", sort: { field: "name", order: "ASC" }, filterDefaultValues: { is_active: true }, disableSyncWithLocation: false, - storeKey: "authorization_groups.embedded", + storeKey: storeKey, }); if (listContext.isLoading) { @@ -31,8 +38,8 @@ const AuthorizationGroupEmbeddedList = () => { return (
- {is_superuser() && } - + {!is_external() && !user && } + {!user && } { + const authorization_group = useRecordContext(); return ( @@ -17,7 +26,7 @@ const ShowActions = () => { filterDefaultValues={{ is_active: true }} storeKey="authorization_groups.embedded" /> - {is_superuser() && } + {authorization_group && authorization_group.is_manager && } ); @@ -49,7 +58,7 @@ const AuthorizationGroupComponent = () => { Users - + {authorization_group.has_product_group_members && ( diff --git a/frontend/src/access_control/users/UserAGEmbeddedList.tsx b/frontend/src/access_control/users/UserAGEmbeddedList.tsx deleted file mode 100644 index 5139dab43..000000000 --- a/frontend/src/access_control/users/UserAGEmbeddedList.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { - BooleanField, - Datagrid, - FilterForm, - Identifier, - ListContextProvider, - NullableBooleanInput, - TextInput, - WithRecord, - useListController, -} from "react-admin"; - -import { CustomPagination } from "../../commons/custom_fields/CustomPagination"; -import TextUrlField from "../../commons/custom_fields/TextUrlField"; -import { is_superuser } from "../../commons/functions"; -import { getSettingListSize } from "../../commons/user_settings/functions"; -import AuthorizationGroupUserAdd from "../authorization_groups/AuthorizationGroupUserAdd"; -import AuthorizationGroupUserRemove from "../authorization_groups/AuthorizationGroupUserRemove"; - -function listFilters() { - if (is_superuser()) { - return [ - , - , - , - , - , - , - ]; - } else { - return [, ]; - } -} - -const showUser = (id: Identifier) => { - return "#/users/" + id + "/show"; -}; - -type UserAGEmbeddedListProps = { - authorization_group: any; -}; - -const UserAGEmbeddedList = ({ authorization_group }: UserAGEmbeddedListProps) => { - const listContext = useListController({ - filter: { authorization_group: Number(authorization_group.id) }, - perPage: 25, - resource: "users", - sort: { field: "username", order: "ASC" }, - filterDefaultValues: { is_active: true }, - disableSyncWithLocation: false, - storeKey: "users.agembedded", - }); - - if (listContext.isLoading) { - return
Loading...
; - } - - localStorage.setItem("useragembeddedlist", "true"); - localStorage.removeItem("userembeddedlist"); - localStorage.setItem("useragembeddedlist.authorization_group", authorization_group.id); - - return ( - -
- {is_superuser() && } - - - } - /> - } - /> - {is_superuser() && } - {is_superuser() && } - {is_superuser() && } - {is_superuser() && } - {is_superuser() && ( - } - /> - )} - - -
-
- ); -}; - -export default UserAGEmbeddedList; diff --git a/frontend/src/access_control/users/UserShow.tsx b/frontend/src/access_control/users/UserShow.tsx index ef011ced5..e2ddc46de 100644 --- a/frontend/src/access_control/users/UserShow.tsx +++ b/frontend/src/access_control/users/UserShow.tsx @@ -1,9 +1,7 @@ import { Box, Paper, Stack, Typography } from "@mui/material"; import { Fragment } from "react"; import { - ArrayField, BooleanField, - Datagrid, DateField, EditButton, Labeled, @@ -17,8 +15,8 @@ import { import { is_superuser } from "../../commons/functions"; import { useStyles } from "../../commons/layout/themes"; -import { getSettingListSize } from "../../commons/user_settings/functions"; import UserProductMemberEmbeddedList from "../../core/product_members/UserProductMemberEmbeddedList"; +import AuthorizationGroupEmbeddedList from "../authorization_groups/AuthorizationGroupEmbeddedList"; import UserChangePassword from "./UserChangePassword"; const ShowActions = () => { @@ -60,10 +58,6 @@ const ShowActions = () => { ); }; -const ShowAuthorizationGroup = (id: any) => { - return "../../../../authorization_groups/" + id + "/show"; -}; - const UserComponent = () => { const { classes } = useStyles(); const current_user = localStorage.getItem("user"); @@ -164,21 +158,12 @@ const UserComponent = () => { )} - {showFullInformation(user) && user.authorization_groups && user.authorization_groups.length > 0 && ( + {showFullInformation(user) && user.has_authorization_groups && ( Authorization Groups - - - - - {" "} - + )} {showFullInformation(user) && user.has_product_group_members && ( diff --git a/frontend/src/commons/functions.tsx b/frontend/src/commons/functions.tsx index e9c791f30..252e33200 100644 --- a/frontend/src/commons/functions.tsx +++ b/frontend/src/commons/functions.tsx @@ -173,3 +173,8 @@ export const is_superuser = () => { const user = localStorage.getItem("user"); return user && JSON.parse(user).is_superuser; }; + +export const is_external = () => { + const user = localStorage.getItem("user"); + return user && JSON.parse(user).is_external; +}; diff --git a/frontend/src/core/product_members/ProductMemberEdit.tsx b/frontend/src/core/product_members/ProductMemberEdit.tsx index 477223ede..f237fd9e4 100644 --- a/frontend/src/core/product_members/ProductMemberEdit.tsx +++ b/frontend/src/core/product_members/ProductMemberEdit.tsx @@ -19,6 +19,7 @@ const ProductMemberEdit = () => { if (reason && reason == "backdropClick") return; setOpen(false); }; + const product_member_update = async (data: any) => { const patch = { role: data.role, From b3f128b39eb87d02d5731170be151ded5d0d2e91 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 09:56:00 +0200 Subject: [PATCH 39/44] fix(deps): update dependency django-cors-headers to v4.5.0 (#2036) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 10 +++++----- backend/pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 8074905fd..16c39728c 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -611,13 +611,13 @@ bcrypt = ["bcrypt"] [[package]] name = "django-cors-headers" -version = "4.4.0" +version = "4.5.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "django_cors_headers-4.4.0-py3-none-any.whl", hash = "sha256:5c6e3b7fe870876a1efdfeb4f433782c3524078fa0dc9e0195f6706ce7a242f6"}, - {file = "django_cors_headers-4.4.0.tar.gz", hash = "sha256:92cf4633e22af67a230a1456cb1b7a02bb213d6536d2dcb2a4a24092ea9cebc2"}, + {file = "django_cors_headers-4.5.0-py3-none-any.whl", hash = "sha256:28c1ded847aa70208798de3e42422a782f427b8b720e8d7319d34b654b5978e6"}, + {file = "django_cors_headers-4.5.0.tar.gz", hash = "sha256:6c01a85cf1ec779a7bde621db853aa3ce5c065a5ba8e27df7a9f9e8dac310f4f"}, ] [package.dependencies] @@ -2489,4 +2489,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "023efa21c4edac8f874422236180767f8f1b62438434a68ca7f17e0615f3ec0c" +content-hash = "f3974cf219b85b04fe28319d8f3ea3786669ba0a3e17b4bbd6a5f53877611650" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 20a4fdf96..39986268d 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -23,7 +23,7 @@ whitenoise = "6.7.0" # https://github.com/evansd/whitenoise # Django REST Framework # ------------------------------------------------------------------------------ djangorestframework = "3.15.2" # https://github.com/encode/django-rest-framework -django-cors-headers = "4.4.0" # https://github.com/adamchainz/django-cors-headers +django-cors-headers = "4.5.0" # https://github.com/adamchainz/django-cors-headers # OpenAPI 3 # ------------------------------------------------------------------------------ drf-spectacular = "0.27.2" # https://github.com/tfranzel/drf-spectacular From 10a988f4e25f145839819e0c1bff9c0d59666942 Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Sat, 12 Oct 2024 20:26:23 +0100 Subject: [PATCH 40/44] feat: configurable rules for password validation (#2037) --- .../application/access_control/api/views.py | 29 +++++++++- ...validator_attribute_similarity_and_more.py | 53 ++++++++++++++++++ backend/application/commons/models.py | 16 ++++++ .../api/test_authorization_settings.py | 4 +- frontend/src/commons/custom_validators.ts | 1 + .../src/commons/settings/SettingsEdit.tsx | 56 ++++++++++++++----- .../src/commons/settings/SettingsShow.tsx | 18 ++++++ 7 files changed, 160 insertions(+), 17 deletions(-) create mode 100644 backend/application/commons/migrations/0009_settings_password_validator_attribute_similarity_and_more.py diff --git a/backend/application/access_control/api/views.py b/backend/application/access_control/api/views.py index cba21616a..6b52f7b02 100644 --- a/backend/application/access_control/api/views.py +++ b/backend/application/access_control/api/views.py @@ -1,8 +1,13 @@ import logging from dataclasses import dataclass +from typing import Any from django.contrib.auth import authenticate as django_authenticate from django.contrib.auth.password_validation import ( + CommonPasswordValidator, + MinimumLengthValidator, + NumericPasswordValidator, + UserAttributeSimilarityValidator, password_validators_help_texts, validate_password, ) @@ -73,6 +78,7 @@ create_user_api_token, revoke_user_api_token, ) +from application.commons.models import Settings from application.commons.services.log_message import format_log_message from application.core.models import Product from application.core.queries.product import get_product_by_id @@ -176,7 +182,7 @@ def change_password(self, request, pk=None): # pylint: disable=unused-argument raise ValidationError("Current password is incorrect") try: - validate_password(new_password_1, instance) + validate_password(new_password_1, instance, self._get_password_validators()) except DjangoValidationError as e: raise ValidationError(e.messages) # pylint: disable=raise-missing-from # The DjangoValidationError itself is not relevant and must not be re-raised @@ -198,11 +204,30 @@ def password_rules(self, request): class PasswordRules: password_rules: str - password_rules_text = password_validators_help_texts() + password_rules_text = password_validators_help_texts( + self._get_password_validators() + ) password_rules = PasswordRules("- " + "\n- ".join(password_rules_text)) response_serializer = UserPasswortRulesSerializer(password_rules) return Response(response_serializer.data, status=status.HTTP_200_OK) + def _get_password_validators(self) -> list[Any]: + validators: list[Any] = [] + settings = Settings.load() + validators.append( + MinimumLengthValidator( + min_length=settings.password_validator_minimum_length + ) + ) + if settings.password_validator_common_passwords: + validators.append(CommonPasswordValidator()) + if settings.password_validator_attribute_similarity: + validators.append(UserAttributeSimilarityValidator()) + if settings.password_validator_not_numeric: + validators.append(NumericPasswordValidator()) + + return validators + class AuthorizationGroupViewSet(ModelViewSet): serializer_class = AuthorizationGroupSerializer diff --git a/backend/application/commons/migrations/0009_settings_password_validator_attribute_similarity_and_more.py b/backend/application/commons/migrations/0009_settings_password_validator_attribute_similarity_and_more.py new file mode 100644 index 000000000..b90906d51 --- /dev/null +++ b/backend/application/commons/migrations/0009_settings_password_validator_attribute_similarity_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 5.1.2 on 2024-10-12 17:38 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "commons", + "0008_remove_settings_background_epss_import_crontab_hours_and_more", + ), + ] + + operations = [ + migrations.AddField( + model_name="settings", + name="password_validator_attribute_similarity", + field=models.BooleanField( + default=True, + help_text="Validates that the password is sufficiently different from certain attributes of the user.", + ), + ), + migrations.AddField( + model_name="settings", + name="password_validator_common_passwords", + field=models.BooleanField( + default=True, + help_text="Validates that the password is not a common password.", + ), + ), + migrations.AddField( + model_name="settings", + name="password_validator_minimum_length", + field=models.IntegerField( + default=8, + help_text="Validates that the password is of a minimum length.", + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(4096), + ], + ), + ), + migrations.AddField( + model_name="settings", + name="password_validator_not_numeric", + field=models.BooleanField( + default=True, + help_text="Validate that the password is not entirely numeric.", + ), + ), + ] diff --git a/backend/application/commons/models.py b/backend/application/commons/models.py index 1e013784c..221e685c8 100644 --- a/backend/application/commons/models.py +++ b/backend/application/commons/models.py @@ -199,6 +199,22 @@ class Settings(Model): help_text="Hour crontab expression for API imports (UTC)", ) + password_validator_minimum_length = IntegerField( + default=8, + validators=[MinValueValidator(1), MaxValueValidator(4096)], + help_text="Validates that the password is of a minimum length.", + ) + password_validator_attribute_similarity = BooleanField( + default=True, + help_text="Validates that the password is sufficiently different from certain attributes of the user.", + ) + password_validator_common_passwords = BooleanField( + default=True, help_text="Validates that the password is not a common password." + ) + password_validator_not_numeric = BooleanField( + default=True, help_text="Validate that the password is not entirely numeric." + ) + def save(self, *args, **kwargs): """ Save object to the database. Removes all other entries if there diff --git a/backend/unittests/access_control/api/test_authorization_settings.py b/backend/unittests/access_control/api/test_authorization_settings.py index 66b701011..bc66ac843 100644 --- a/backend/unittests/access_control/api/test_authorization_settings.py +++ b/backend/unittests/access_control/api/test_authorization_settings.py @@ -6,7 +6,7 @@ class TestAuthorizationSettings(TestAuthorizationBase): def test_authorization_settings(self): - expected_data = "{'id': 1, 'security_gate_active': True, 'security_gate_threshold_critical': 0, 'security_gate_threshold_high': 0, 'security_gate_threshold_medium': 99999, 'security_gate_threshold_low': 99999, 'security_gate_threshold_none': 99999, 'security_gate_threshold_unkown': 99999, 'jwt_validity_duration_user': 168, 'jwt_validity_duration_superuser': 24, 'internal_users': '', 'base_url_frontend': '', 'exception_ms_teams_webhook': '', 'exception_slack_webhook': '', 'exception_rate_limit': 3600, 'email_from': '', 'exception_email_to': '', 'background_product_metrics_interval_minutes': 5, 'background_epss_import_crontab_minute': 0, 'background_epss_import_crontab_hour': 3, 'branch_housekeeping_crontab_minute': 0, 'branch_housekeeping_crontab_hour': 2, 'branch_housekeeping_active': True, 'branch_housekeeping_keep_inactive_days': 30, 'branch_housekeeping_exempt_branches': '', 'feature_vex': False, 'feature_disable_user_login': False, 'feature_general_rules_need_approval': False, 'risk_acceptance_expiry_days': 30, 'risk_acceptance_expiry_crontab_minute': 0, 'risk_acceptance_expiry_crontab_hour': 1, 'feature_automatic_api_import': True, 'api_import_crontab_minute': 0, 'api_import_crontab_hour': 4}" + expected_data = "{'id': 1, 'security_gate_active': True, 'security_gate_threshold_critical': 0, 'security_gate_threshold_high': 0, 'security_gate_threshold_medium': 99999, 'security_gate_threshold_low': 99999, 'security_gate_threshold_none': 99999, 'security_gate_threshold_unkown': 99999, 'jwt_validity_duration_user': 168, 'jwt_validity_duration_superuser': 24, 'internal_users': '', 'base_url_frontend': '', 'exception_ms_teams_webhook': '', 'exception_slack_webhook': '', 'exception_rate_limit': 3600, 'email_from': '', 'exception_email_to': '', 'background_product_metrics_interval_minutes': 5, 'background_epss_import_crontab_minute': 0, 'background_epss_import_crontab_hour': 3, 'branch_housekeeping_crontab_minute': 0, 'branch_housekeeping_crontab_hour': 2, 'branch_housekeeping_active': True, 'branch_housekeeping_keep_inactive_days': 30, 'branch_housekeeping_exempt_branches': '', 'feature_vex': False, 'feature_disable_user_login': False, 'feature_general_rules_need_approval': False, 'risk_acceptance_expiry_days': 30, 'risk_acceptance_expiry_crontab_minute': 0, 'risk_acceptance_expiry_crontab_hour': 1, 'feature_automatic_api_import': True, 'api_import_crontab_minute': 0, 'api_import_crontab_hour': 4, 'password_validator_minimum_length': 8, 'password_validator_attribute_similarity': True, 'password_validator_common_passwords': True, 'password_validator_not_numeric': True}" self._test_api( APITest("db_admin", "get", "/api/settings/1/", None, 200, expected_data) ) @@ -16,7 +16,7 @@ def test_authorization_settings(self): ) post_data = {"security_gate_threshold_critical": 1234} - expected_data = "{'id': 1, 'security_gate_active': True, 'security_gate_threshold_critical': 1234, 'security_gate_threshold_high': 0, 'security_gate_threshold_medium': 99999, 'security_gate_threshold_low': 99999, 'security_gate_threshold_none': 99999, 'security_gate_threshold_unkown': 99999, 'jwt_validity_duration_user': 168, 'jwt_validity_duration_superuser': 24, 'internal_users': '', 'base_url_frontend': '', 'exception_ms_teams_webhook': '', 'exception_slack_webhook': '', 'exception_rate_limit': 3600, 'email_from': '', 'exception_email_to': '', 'background_product_metrics_interval_minutes': 5, 'background_epss_import_crontab_minute': 0, 'background_epss_import_crontab_hour': 3, 'branch_housekeeping_crontab_minute': 0, 'branch_housekeeping_crontab_hour': 2, 'branch_housekeeping_active': True, 'branch_housekeeping_keep_inactive_days': 30, 'branch_housekeeping_exempt_branches': '', 'feature_vex': False, 'feature_disable_user_login': False, 'feature_general_rules_need_approval': False, 'risk_acceptance_expiry_days': 30, 'risk_acceptance_expiry_crontab_minute': 0, 'risk_acceptance_expiry_crontab_hour': 1, 'feature_automatic_api_import': True, 'api_import_crontab_minute': 0, 'api_import_crontab_hour': 4}" + expected_data = "{'id': 1, 'security_gate_active': True, 'security_gate_threshold_critical': 1234, 'security_gate_threshold_high': 0, 'security_gate_threshold_medium': 99999, 'security_gate_threshold_low': 99999, 'security_gate_threshold_none': 99999, 'security_gate_threshold_unkown': 99999, 'jwt_validity_duration_user': 168, 'jwt_validity_duration_superuser': 24, 'internal_users': '', 'base_url_frontend': '', 'exception_ms_teams_webhook': '', 'exception_slack_webhook': '', 'exception_rate_limit': 3600, 'email_from': '', 'exception_email_to': '', 'background_product_metrics_interval_minutes': 5, 'background_epss_import_crontab_minute': 0, 'background_epss_import_crontab_hour': 3, 'branch_housekeeping_crontab_minute': 0, 'branch_housekeeping_crontab_hour': 2, 'branch_housekeeping_active': True, 'branch_housekeeping_keep_inactive_days': 30, 'branch_housekeeping_exempt_branches': '', 'feature_vex': False, 'feature_disable_user_login': False, 'feature_general_rules_need_approval': False, 'risk_acceptance_expiry_days': 30, 'risk_acceptance_expiry_crontab_minute': 0, 'risk_acceptance_expiry_crontab_hour': 1, 'feature_automatic_api_import': True, 'api_import_crontab_minute': 0, 'api_import_crontab_hour': 4, 'password_validator_minimum_length': 8, 'password_validator_attribute_similarity': True, 'password_validator_common_passwords': True, 'password_validator_not_numeric': True}" self._test_api( APITest( "db_admin", diff --git a/frontend/src/commons/custom_validators.ts b/frontend/src/commons/custom_validators.ts index 9314d96e5..60e2c15ac 100644 --- a/frontend/src/commons/custom_validators.ts +++ b/frontend/src/commons/custom_validators.ts @@ -16,6 +16,7 @@ export const validate_0_10 = [minValue(0), maxValue(10)]; export const validate_0_999999 = [minValue(0), maxValue(999999)]; export const validate_0_23 = [minValue(0), maxValue(23)]; export const validate_0_59 = [minValue(0), maxValue(59)]; +export const validate_1_4096 = [minValue(1), maxValue(4096)]; export const validate_2000_9999 = [minValue(2000), maxValue(9999)]; export function validate_after_today() { diff --git a/frontend/src/commons/settings/SettingsEdit.tsx b/frontend/src/commons/settings/SettingsEdit.tsx index 666e12a25..9d660d8e5 100644 --- a/frontend/src/commons/settings/SettingsEdit.tsx +++ b/frontend/src/commons/settings/SettingsEdit.tsx @@ -3,7 +3,13 @@ import { Fragment } from "react"; import { BooleanInput, Edit, FormDataConsumer, NumberInput, SaveButton, SimpleForm, Toolbar } from "react-admin"; import settings from "."; -import { validate_0_23, validate_0_59, validate_0_999999, validate_255 } from "../../commons/custom_validators"; +import { + validate_0_23, + validate_0_59, + validate_0_999999, + validate_1_4096, + validate_255, +} from "../../commons/custom_validators"; import ListHeader from "../../commons/layout/ListHeader"; import { TextInputWide } from "../../commons/layout/themes"; @@ -312,7 +318,7 @@ const SettingsEdit = () => { helperText="Days before risk acceptance expires, 0 means no expiry" sx={{ marginBottom: 2 }} /> - + { step={1} validate={validate_0_23} helperText="Hour crontab expression for checking risk acceptance expiry (UTC)" - sx={{ marginBottom: 2 }} /> { step={1} validate={validate_0_59} helperText="Minute crontab expression for checking risk acceptance expiry" - sx={{ marginBottom: 2 }} /> - + Automatic API import - + {({ formData }) => formData.feature_automatic_api_import && ( - + { step={1} validate={validate_0_23} helperText="Hour crontab expression for API imports (UTC)" - sx={{ marginBottom: 2 }} /> { step={1} validate={validate_0_59} helperText="Minute crontab expression for API imports" - sx={{ marginBottom: 2 }} /> ) } + + + + Password validation for non-OIDC users + + + + + diff --git a/frontend/src/commons/settings/SettingsShow.tsx b/frontend/src/commons/settings/SettingsShow.tsx index 97a4e70b6..af9b0c192 100644 --- a/frontend/src/commons/settings/SettingsShow.tsx +++ b/frontend/src/commons/settings/SettingsShow.tsx @@ -196,6 +196,24 @@ const SettingsShowComponent = () => { )}
+ + + Password validation for non-OIDC users + + + + + + + + + + + + + + + )} /> From e0cc537a87199d0ce3d472c23a0663e06a631754 Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Sun, 13 Oct 2024 21:08:49 +0100 Subject: [PATCH 41/44] feat: button to toggle theme (light/dark) in the app bar (#2038) --- frontend/src/commons/layout/AppBar.tsx | 2 + .../src/commons/layout/ToggleThemeButton.tsx | 47 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 frontend/src/commons/layout/ToggleThemeButton.tsx diff --git a/frontend/src/commons/layout/AppBar.tsx b/frontend/src/commons/layout/AppBar.tsx index b89f7313e..5d89c0d90 100644 --- a/frontend/src/commons/layout/AppBar.tsx +++ b/frontend/src/commons/layout/AppBar.tsx @@ -8,6 +8,7 @@ import { Link } from "react-router-dom"; import About from "../about/About"; import Logo from "./Logo"; +import ToggleThemeButton from "./ToggleThemeButton"; const DocumentationMenu = forwardRef(() => { const userMenuContext = useUserMenu(); @@ -108,6 +109,7 @@ const CustomAppBar = () => { userMenu={} toolbar={ <> + } diff --git a/frontend/src/commons/layout/ToggleThemeButton.tsx b/frontend/src/commons/layout/ToggleThemeButton.tsx new file mode 100644 index 000000000..bcf2801f9 --- /dev/null +++ b/frontend/src/commons/layout/ToggleThemeButton.tsx @@ -0,0 +1,47 @@ +import DarkModeIcon from "@mui/icons-material/DarkMode"; +import LightModeIcon from "@mui/icons-material/LightMode"; +import { IconButton, Tooltip } from "@mui/material"; +import { useTheme } from "react-admin"; + +import { getSettingTheme, saveSettingTheme } from "../../commons/user_settings/functions"; + +const tooltipTitle = () => { + const theme = getSettingTheme(); + return theme === "dark" ? "Light mode" : "Dark mode"; +}; + +const ThemeIcon = () => { + const theme = getSettingTheme(); + return theme === "dark" ? ( + + ) : ( + + ); +}; + +const ToggleThemeButton = () => { + const [, setTheme] = useTheme(); + + const toogleTheme = () => { + const theme = getSettingTheme(); + if (theme === "dark") { + setTheme("light"); + localStorage.setItem("theme", "light"); + saveSettingTheme("light"); + } else { + setTheme("dark"); + localStorage.setItem("theme", "dark"); + saveSettingTheme("dark"); + } + }; + + return ( + + + + + + ); +}; + +export default ToggleThemeButton; From 025576f215e2f60d3efe32a18bd24fc3dc542de7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 07:27:20 +0100 Subject: [PATCH 42/44] fix(deps): update dependency coverage to v7.6.3 (#2039) --- backend/poetry.lock | 128 ++++++++++++++++++++--------------------- backend/pyproject.toml | 2 +- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 16c39728c..0231b5446 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -398,73 +398,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.2" +version = "7.6.3" description = "Code coverage measurement for Python" optional = true python-versions = ">=3.9" files = [ - {file = "coverage-7.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667"}, - {file = "coverage-7.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345"}, - {file = "coverage-7.6.2-cp310-cp310-win32.whl", hash = "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676"}, - {file = "coverage-7.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02"}, - {file = "coverage-7.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b"}, - {file = "coverage-7.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0"}, - {file = "coverage-7.6.2-cp311-cp311-win32.whl", hash = "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438"}, - {file = "coverage-7.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b"}, - {file = "coverage-7.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c"}, - {file = "coverage-7.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b"}, - {file = "coverage-7.6.2-cp312-cp312-win32.whl", hash = "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276"}, - {file = "coverage-7.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0"}, - {file = "coverage-7.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40"}, - {file = "coverage-7.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869"}, - {file = "coverage-7.6.2-cp313-cp313-win32.whl", hash = "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530"}, - {file = "coverage-7.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36"}, - {file = "coverage-7.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef"}, - {file = "coverage-7.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db"}, - {file = "coverage-7.6.2-cp313-cp313t-win32.whl", hash = "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171"}, - {file = "coverage-7.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a"}, - {file = "coverage-7.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5"}, - {file = "coverage-7.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627"}, - {file = "coverage-7.6.2-cp39-cp39-win32.whl", hash = "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0"}, - {file = "coverage-7.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c"}, - {file = "coverage-7.6.2-pp39.pp310-none-any.whl", hash = "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e"}, - {file = "coverage-7.6.2.tar.gz", hash = "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3"}, + {file = "coverage-7.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976"}, + {file = "coverage-7.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e"}, + {file = "coverage-7.6.3-cp310-cp310-win32.whl", hash = "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007"}, + {file = "coverage-7.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd"}, + {file = "coverage-7.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b"}, + {file = "coverage-7.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f"}, + {file = "coverage-7.6.3-cp311-cp311-win32.whl", hash = "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97"}, + {file = "coverage-7.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6"}, + {file = "coverage-7.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6"}, + {file = "coverage-7.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167"}, + {file = "coverage-7.6.3-cp312-cp312-win32.whl", hash = "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd"}, + {file = "coverage-7.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6"}, + {file = "coverage-7.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6"}, + {file = "coverage-7.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4"}, + {file = "coverage-7.6.3-cp313-cp313-win32.whl", hash = "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f"}, + {file = "coverage-7.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce"}, + {file = "coverage-7.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3"}, + {file = "coverage-7.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91"}, + {file = "coverage-7.6.3-cp313-cp313t-win32.whl", hash = "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43"}, + {file = "coverage-7.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0"}, + {file = "coverage-7.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2"}, + {file = "coverage-7.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13"}, + {file = "coverage-7.6.3-cp39-cp39-win32.whl", hash = "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3"}, + {file = "coverage-7.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d"}, + {file = "coverage-7.6.3-pp39.pp310-none-any.whl", hash = "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181"}, + {file = "coverage-7.6.3.tar.gz", hash = "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054"}, ] [package.extras] @@ -2489,4 +2489,4 @@ unittests = ["coverage", "django-coverage-plugin", "django-extensions"] [metadata] lock-version = "2.0" python-versions = ">= 3.10, < 3.13" -content-hash = "f3974cf219b85b04fe28319d8f3ea3786669ba0a3e17b4bbd6a5f53877611650" +content-hash = "565acf4ba370c447c86b8c7ce4edd625d64c6b3a1cca37e220bc723094333191" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 39986268d..d30cb6d8e 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -69,7 +69,7 @@ django-extensions = { version = "3.2.3", optional = true } # https://github.com # Unittest dependencies # ------------------------------------------------------------------------------ -coverage = { version = "7.6.2", optional = true } # https://github.com/nedbat/coveragepy +coverage = { version = "7.6.3", optional = true } # https://github.com/nedbat/coveragepy django-coverage-plugin = { version = "3.1.0", optional = true } # https://github.com/nedbat/django_coverage_plugin # Code quality dependencies From 6918d8cf551e88ec3bc1305a7cffef9c8b3824ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:44:47 +0200 Subject: [PATCH 43/44] chore(deps): lock file maintenance (#2004) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- backend/poetry.lock | 358 +++++++++++++++++++------------------ frontend/package-lock.json | 161 +++++++++-------- 2 files changed, 270 insertions(+), 249 deletions(-) diff --git a/backend/poetry.lock b/backend/poetry.lock index 0231b5446..1e9cbdc51 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -76,13 +76,13 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "astroid" -version = "3.3.4" +version = "3.3.5" description = "An abstract syntax tree for Python with inference support." optional = true python-versions = ">=3.9.0" files = [ - {file = "astroid-3.3.4-py3-none-any.whl", hash = "sha256:5eba185467253501b62a9f113c263524b4f5d55e1b30456370eed4cdbd6438fd"}, - {file = "astroid-3.3.4.tar.gz", hash = "sha256:e73d0b62dd680a7c07cb2cd0ce3c22570b044dd01bd994bc3a2dd16c6cbba162"}, + {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, + {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, ] [package.dependencies] @@ -274,101 +274,116 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, ] [[package]] @@ -580,13 +595,13 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "distlib" -version = "0.3.8" +version = "0.3.9" description = "Distribution utilities" optional = true python-versions = "*" files = [ - {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, - {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, ] [[package]] @@ -810,21 +825,21 @@ markdown = ["types-Markdown (>=0.1.5)"] [[package]] name = "dnspython" -version = "2.6.1" +version = "2.7.0" description = "DNS toolkit" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"}, - {file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"}, + {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, + {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, ] [package.extras] -dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "sphinx (>=7.2.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] -dnssec = ["cryptography (>=41)"] +dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "hypercorn (>=0.16.0)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "quart-trio (>=0.11.0)", "sphinx (>=7.2.0)", "sphinx-rtd-theme (>=2.0.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] +dnssec = ["cryptography (>=43)"] doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"] -doq = ["aioquic (>=0.9.25)"] -idna = ["idna (>=3.6)"] +doq = ["aioquic (>=1.0.0)"] +idna = ["idna (>=3.7)"] trio = ["trio (>=0.23)"] wmi = ["wmi (>=1.5.1)"] @@ -1219,13 +1234,13 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jsonschema-specifications" -version = "2023.12.1" +version = "2024.10.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, - {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, + {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, + {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, ] [package.dependencies] @@ -1233,71 +1248,72 @@ referencing = ">=0.31.0" [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.1" description = "Safely add untrusted strings to HTML/XML markup." optional = true -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, + {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, ] [[package]] diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 97c89c6da..e17ca47a5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -126,9 +126,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", - "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", "dev": true, "license": "MIT", "engines": { @@ -136,9 +136,9 @@ } }, "node_modules/@babel/core": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", - "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, "license": "MIT", "dependencies": { @@ -148,10 +148,10 @@ "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-module-transforms": "^7.25.7", "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.7", + "@babel/parser": "^7.25.8", "@babel/template": "^7.25.7", "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7", + "@babel/types": "^7.25.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -392,12 +392,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", - "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.7" + "@babel/types": "^7.25.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -492,9 +492,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.7", @@ -1684,6 +1684,7 @@ "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { @@ -2019,9 +2020,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.17", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.17.tgz", - "integrity": "sha512-oyumoJgB6jDV8JFzRqjBo2daUuHpzDjoO/e3IrRhhHo/FxJlaVhET6mcNrKHUq2E+R+q3ql0qAtvQ4rfWHhAeQ==", + "version": "7.2.18", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.18.tgz", + "integrity": "sha512-uvK9dWeyCJl/3ocVnTOS6nlji/Knj8/tVqVX03UVTpdmTJYu/s4jtDd9Kvv0nRGE0CUSNW1UYAci7PYypjealg==", "license": "MIT", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -2357,9 +2358,9 @@ "license": "MIT" }, "node_modules/@tanstack/query-core": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.0.tgz", - "integrity": "sha512-WGD8uIhX6/deH/tkZqPNcRyAhDUqs729bWKoByYHSogcshXfFbppOdTER5+qY7mFvu8KEFJwT0nxr8RfPTVh0Q==", + "version": "5.59.13", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.13.tgz", + "integrity": "sha512-Oou0bBu/P8+oYjXsJQ11j+gcpLAMpqW42UlokQYEz4dE7+hOtVO9rVuolJKgEccqzvyFzqX4/zZWY+R/v1wVsQ==", "license": "MIT", "funding": { "type": "github", @@ -2367,12 +2368,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.0.tgz", - "integrity": "sha512-YDXp3OORbYR+8HNQx+lf4F73NoiCmCcSvZvgxE29OifmQFk0sBlO26NWLHpcNERo92tVk3w+JQ53/vkcRUY1hA==", + "version": "5.59.13", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.13.tgz", + "integrity": "sha512-GB2ELtiH8tL0rcFiM4sWvnXhazt1xRXX/LolMEV12kfEKu58aNA4lQoieslP61PO4vZO9JJMwm+6lqyS0E1HOA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.59.0" + "@tanstack/query-core": "5.59.13" }, "funding": { "type": "github", @@ -2963,9 +2964,9 @@ } }, "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse/node_modules/@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "dev": true, "license": "MIT", "dependencies": { @@ -3715,9 +3716,9 @@ "license": "MIT" }, "node_modules/attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.4.tgz", + "integrity": "sha512-2pA6xFIbdTUDCAwjN8nQwI+842VwzbDUXO2IYlpPXQIORgKnavorcr4Ce3rwh+zsNg9zK7QPsdvDj3Lum4WX4w==", "license": "MIT", "engines": { "node": ">=4" @@ -3867,9 +3868,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", "dev": true, "funding": [ { @@ -4031,9 +4032,9 @@ "license": "MIT" }, "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", "license": "MIT" }, "node_modules/convert-source-map": { @@ -4803,9 +4804,9 @@ "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/electron-to-chromium": { - "version": "1.5.32", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz", - "integrity": "sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==", + "version": "1.5.36", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.36.tgz", + "integrity": "sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==", "dev": true, "license": "ISC" }, @@ -4919,9 +4920,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", "dev": true, "license": "MIT", "dependencies": { @@ -4932,12 +4933,12 @@ "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", + "iterator.prototype": "^1.1.3", "safe-array-concat": "^1.1.2" }, "engines": { @@ -5154,9 +5155,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "5.1.0-rc-0751fac7-20241002", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-0751fac7-20241002.tgz", - "integrity": "sha512-9CEhaksLMmjRIpLdm5xazaCvDYsLZ0OKgCBQTyuiP4LvtB1wiQVBVGgQVWF1iC2FZmilFsefdmxUJb0nQl80Yg==", + "version": "5.1.0-rc-cd22717c-20241013", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-cd22717c-20241013.tgz", + "integrity": "sha512-p4gcOd9uRugj0w+23DAcb1quxz0RLLQrebiQ2wQ3+LbRlSic5SwixqdZmMsuQLkKdWYYftVIH6gsBoUBHNdsZg==", "dev": true, "license": "MIT", "engines": { @@ -5614,9 +5615,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -6448,9 +6449,9 @@ "license": "ISC" }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6459,6 +6460,9 @@ "has-symbols": "^1.0.3", "reflect.getprototypeof": "^1.0.4", "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/javascript-natural-sort": { @@ -7283,15 +7287,15 @@ } }, "node_modules/mlly": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", - "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", + "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", "license": "MIT", "dependencies": { - "acorn": "^8.11.3", + "acorn": "^8.12.1", "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" } }, "node_modules/ms": { @@ -7527,9 +7531,9 @@ } }, "node_modules/package-manager-detector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", - "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.2.tgz", + "integrity": "sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==", "license": "MIT" }, "node_modules/parent-module": { @@ -7639,13 +7643,13 @@ } }, "node_modules/pkg-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", - "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", "license": "MIT", "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.7.1", + "confbox": "^0.1.8", + "mlly": "^1.7.2", "pathe": "^1.1.2" } }, @@ -7794,14 +7798,14 @@ } }, "node_modules/prosemirror-commands": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.0.tgz", - "integrity": "sha512-xn1U/g36OqXn2tn5nGmvnnimAj/g1pUx2ypJJIe8WkVX83WyJVC5LTARaxZa2AtQRwntu9Jc5zXs9gL9svp/mg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.1.tgz", + "integrity": "sha512-tNy4uaGWzvuUYXDke7B28krndIrdQJhSh0OLpubtwtEwFbjItOj/eoAfPvstBJyyV0S2+b5t4G+4XPXdxar6pg==", "license": "MIT", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.0.0" + "prosemirror-transform": "^1.10.2" } }, "node_modules/prosemirror-dropcursor": { @@ -7883,9 +7887,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.3.tgz", - "integrity": "sha512-V4XCysitErI+i0rKFILGt/xClnFJaohe/wrrlT2NSZ+zk8ggQfDH4x2wNK7Gm0Hp4CIoWizvXFP7L9KMaCuI0Q==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.23.0.tgz", + "integrity": "sha512-Q/fgsgl/dlOAW9ILu4OOhYWQbc7TQd4BwKH/RwmUjyVf8682Be4zj3rOYdLnYEcGzyg8LL9Q5IWYKD8tdToreQ==", "license": "MIT", "dependencies": { "orderedmap": "^2.0.0" @@ -7951,9 +7955,9 @@ } }, "node_modules/prosemirror-transform": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.0.tgz", - "integrity": "sha512-9UOgFSgN6Gj2ekQH5CTDJ8Rp/fnKR2IkYfGdzzp5zQMFsS4zDllLVx/+jGcX86YlACpG7UR5fwAXiWzxqWtBTg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz", + "integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==", "license": "MIT", "dependencies": { "prosemirror-model": "^1.21.0" @@ -8639,6 +8643,7 @@ "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { From 0f3b714e6decb6ed36952307e18fce24681b8775 Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Mon, 14 Oct 2024 10:24:32 +0100 Subject: [PATCH 44/44] chore: prepare for release 1.20.0 (#2040) --- .github/workflows/scan_sca_current.yml | 2 +- backend/application/__init__.py | 2 +- backend/pyproject.toml | 2 +- .../vex/api/files/csaf_given_vulnerability.json | 2 +- .../api/files/csaf_given_vulnerability_update.json | 2 +- .../vex/api/files/csaf_product_branches.json | 2 +- .../vex/api/files/csaf_product_given_branch.json | 2 +- .../vex/api/files/csaf_product_no_branch.json | 2 +- .../vex/api/files/csaf_product_no_branch_update.json | 2 +- .../vex/api/files/openvex_given_vulnerability.json | 2 +- .../files/openvex_given_vulnerability_update.json | 2 +- .../vex/api/files/openvex_product_branches.json | 2 +- .../vex/api/files/openvex_product_given_branch.json | 2 +- .../vex/api/files/openvex_product_no_branch.json | 2 +- .../api/files/openvex_product_no_branch_update.json | 2 +- .../vex/services/files/so_csaf_2024_0001_0001.json | 2 +- .../services/files/so_csaf_2024_0001_0001_short.json | 2 +- .../services/files/so_openvex_2024_0001_0001.json | 2 +- docker-compose-prod-mysql.yml | 4 ++-- docker-compose-prod-postgres.yml | 4 ++-- docs/getting_started/installation.md | 4 ++-- end_to_end_tests/package-lock.json | 4 ++-- end_to_end_tests/package.json | 2 +- frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- so_configuration_sca_current.yml | 12 ++++++------ 26 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/scan_sca_current.yml b/.github/workflows/scan_sca_current.yml index 2549ed6e4..28fb28b40 100644 --- a/.github/workflows/scan_sca_current.yml +++ b/.github/workflows/scan_sca_current.yml @@ -15,7 +15,7 @@ jobs: name: Checkout uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: - ref: 'v1.19.0' + ref: 'v1.20.0' - name: Run SCA vulnerability scanners uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@70451f5f17e1de8fddcaebb767167a279dc8815b # main diff --git a/backend/application/__init__.py b/backend/application/__init__.py index 4374f0159..0107b31aa 100644 --- a/backend/application/__init__.py +++ b/backend/application/__init__.py @@ -1,4 +1,4 @@ -__version__ = "1.19.0" +__version__ = "1.20.0" import pymysql diff --git a/backend/pyproject.toml b/backend/pyproject.toml index d30cb6d8e..a536bbd28 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "SecObserve" -version = "1.19.0" +version = "1.20.0" description = "SecObserve is an open source vulnerability management system for software development and cloud environments." license = "BSD-3-Clause" authors = [ diff --git a/backend/unittests/vex/api/files/csaf_given_vulnerability.json b/backend/unittests/vex/api/files/csaf_given_vulnerability.json index 8ea751883..681727693 100644 --- a/backend/unittests/vex/api/files/csaf_given_vulnerability.json +++ b/backend/unittests/vex/api/files/csaf_given_vulnerability.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "CSAF_2024_0001_0001", diff --git a/backend/unittests/vex/api/files/csaf_given_vulnerability_update.json b/backend/unittests/vex/api/files/csaf_given_vulnerability_update.json index 14f8d7e1d..07bb9ca3c 100644 --- a/backend/unittests/vex/api/files/csaf_given_vulnerability_update.json +++ b/backend/unittests/vex/api/files/csaf_given_vulnerability_update.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "CSAF_2024_0001_0002", diff --git a/backend/unittests/vex/api/files/csaf_product_branches.json b/backend/unittests/vex/api/files/csaf_product_branches.json index 6d8bf129d..b41a99fb8 100644 --- a/backend/unittests/vex/api/files/csaf_product_branches.json +++ b/backend/unittests/vex/api/files/csaf_product_branches.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "CSAF_2024_0001_0001", diff --git a/backend/unittests/vex/api/files/csaf_product_given_branch.json b/backend/unittests/vex/api/files/csaf_product_given_branch.json index 7204e7d8f..cf20c0a7c 100644 --- a/backend/unittests/vex/api/files/csaf_product_given_branch.json +++ b/backend/unittests/vex/api/files/csaf_product_given_branch.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "CSAF_2024_0001_0001", diff --git a/backend/unittests/vex/api/files/csaf_product_no_branch.json b/backend/unittests/vex/api/files/csaf_product_no_branch.json index b0dee5766..124ac5f71 100644 --- a/backend/unittests/vex/api/files/csaf_product_no_branch.json +++ b/backend/unittests/vex/api/files/csaf_product_no_branch.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "CSAF_2024_0001_0001", diff --git a/backend/unittests/vex/api/files/csaf_product_no_branch_update.json b/backend/unittests/vex/api/files/csaf_product_no_branch_update.json index 5d85ea206..42e69b355 100644 --- a/backend/unittests/vex/api/files/csaf_product_no_branch_update.json +++ b/backend/unittests/vex/api/files/csaf_product_no_branch_update.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "CSAF_2024_0001_0002", diff --git a/backend/unittests/vex/api/files/openvex_given_vulnerability.json b/backend/unittests/vex/api/files/openvex_given_vulnerability.json index a883ae2b3..af575b481 100644 --- a/backend/unittests/vex/api/files/openvex_given_vulnerability.json +++ b/backend/unittests/vex/api/files/openvex_given_vulnerability.json @@ -47,6 +47,6 @@ } ], "timestamp": "2020-01-01T04:30:00+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 1 } \ No newline at end of file diff --git a/backend/unittests/vex/api/files/openvex_given_vulnerability_update.json b/backend/unittests/vex/api/files/openvex_given_vulnerability_update.json index 92fadf67b..fc3cbf780 100644 --- a/backend/unittests/vex/api/files/openvex_given_vulnerability_update.json +++ b/backend/unittests/vex/api/files/openvex_given_vulnerability_update.json @@ -37,6 +37,6 @@ } ], "timestamp": "2020-01-01T04:30:00+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 2 } \ No newline at end of file diff --git a/backend/unittests/vex/api/files/openvex_product_branches.json b/backend/unittests/vex/api/files/openvex_product_branches.json index 13193608d..25958d949 100644 --- a/backend/unittests/vex/api/files/openvex_product_branches.json +++ b/backend/unittests/vex/api/files/openvex_product_branches.json @@ -70,6 +70,6 @@ } ], "timestamp": "2020-01-01T04:30:00+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 1 } \ No newline at end of file diff --git a/backend/unittests/vex/api/files/openvex_product_given_branch.json b/backend/unittests/vex/api/files/openvex_product_given_branch.json index 9fbf2e08a..e433c6010 100644 --- a/backend/unittests/vex/api/files/openvex_product_given_branch.json +++ b/backend/unittests/vex/api/files/openvex_product_given_branch.json @@ -28,6 +28,6 @@ } ], "timestamp": "2020-01-01T04:30:00+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 1 } \ No newline at end of file diff --git a/backend/unittests/vex/api/files/openvex_product_no_branch.json b/backend/unittests/vex/api/files/openvex_product_no_branch.json index 506820670..e33721ebf 100644 --- a/backend/unittests/vex/api/files/openvex_product_no_branch.json +++ b/backend/unittests/vex/api/files/openvex_product_no_branch.json @@ -63,6 +63,6 @@ } ], "timestamp": "2020-01-01T04:30:00+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 1 } \ No newline at end of file diff --git a/backend/unittests/vex/api/files/openvex_product_no_branch_update.json b/backend/unittests/vex/api/files/openvex_product_no_branch_update.json index 3de041876..12884c500 100644 --- a/backend/unittests/vex/api/files/openvex_product_no_branch_update.json +++ b/backend/unittests/vex/api/files/openvex_product_no_branch_update.json @@ -64,6 +64,6 @@ } ], "timestamp": "2020-01-01T04:30:00+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 2 } \ No newline at end of file diff --git a/backend/unittests/vex/services/files/so_csaf_2024_0001_0001.json b/backend/unittests/vex/services/files/so_csaf_2024_0001_0001.json index 90bf847e9..7738596ec 100644 --- a/backend/unittests/vex/services/files/so_csaf_2024_0001_0001.json +++ b/backend/unittests/vex/services/files/so_csaf_2024_0001_0001.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "so_2024_0001_0001", diff --git a/backend/unittests/vex/services/files/so_csaf_2024_0001_0001_short.json b/backend/unittests/vex/services/files/so_csaf_2024_0001_0001_short.json index 07cd052a4..eb5f0f89b 100644 --- a/backend/unittests/vex/services/files/so_csaf_2024_0001_0001_short.json +++ b/backend/unittests/vex/services/files/so_csaf_2024_0001_0001_short.json @@ -18,7 +18,7 @@ "generator": { "engine": { "name": "SecObserve", - "version": "1.19.0" + "version": "1.20.0" } }, "id": "so_2024_0001_0001", diff --git a/backend/unittests/vex/services/files/so_openvex_2024_0001_0001.json b/backend/unittests/vex/services/files/so_openvex_2024_0001_0001.json index f68d8de70..45c8793d5 100644 --- a/backend/unittests/vex/services/files/so_openvex_2024_0001_0001.json +++ b/backend/unittests/vex/services/files/so_openvex_2024_0001_0001.json @@ -294,6 +294,6 @@ } ], "timestamp": "2024-07-14T11:17:57.668593+00:00", - "tooling": "SecObserve / 1.19.0", + "tooling": "SecObserve / 1.20.0", "version": 1 } \ No newline at end of file diff --git a/docker-compose-prod-mysql.yml b/docker-compose-prod-mysql.yml index c2a98597f..70ee64901 100644 --- a/docker-compose-prod-mysql.yml +++ b/docker-compose-prod-mysql.yml @@ -35,7 +35,7 @@ services: - traefik frontend: - image: maibornwolff/secobserve-frontend:1.19.0 + image: maibornwolff/secobserve-frontend:1.20.0 container_name: "prod_secobserve_frontend" labels: - "traefik.enable=true" @@ -54,7 +54,7 @@ services: - traefik backend: - image: maibornwolff/secobserve-backend:1.19.0 + image: maibornwolff/secobserve-backend:1.20.0 container_name: "prod_secobserve_backend" labels: - "traefik.enable=true" diff --git a/docker-compose-prod-postgres.yml b/docker-compose-prod-postgres.yml index 7a9f0c09f..f08d3e53d 100644 --- a/docker-compose-prod-postgres.yml +++ b/docker-compose-prod-postgres.yml @@ -35,7 +35,7 @@ services: - traefik frontend: - image: maibornwolff/secobserve-frontend:1.19.0 + image: maibornwolff/secobserve-frontend:1.20.0 container_name: "prod_secobserve_frontend" labels: - "traefik.enable=true" @@ -54,7 +54,7 @@ services: - traefik backend: - image: maibornwolff/secobserve-backend:1.19.0 + image: maibornwolff/secobserve-backend:1.20.0 container_name: "prod_secobserve_backend" labels: - "traefik.enable=true" diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index b9a1e7497..75962102a 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -45,7 +45,7 @@ services: - default frontend: - image: maibornwolff/secobserve-frontend:1.19.0 + image: maibornwolff/secobserve-frontend:1.20.0 labels: - "traefik.enable=true" - "traefik.http.routers.frontend.rule=Host(`secobserve.localhost`)" @@ -62,7 +62,7 @@ services: - traefik backend: - image: maibornwolff/secobserve-backend:1.19.0 + image: maibornwolff/secobserve-backend:1.20.0 labels: - "traefik.enable=true" - "traefik.http.routers.backend.rule=Host(`secobserve-backend.localhost`)" diff --git a/end_to_end_tests/package-lock.json b/end_to_end_tests/package-lock.json index 871bbbef2..741a41785 100644 --- a/end_to_end_tests/package-lock.json +++ b/end_to_end_tests/package-lock.json @@ -1,12 +1,12 @@ { "name": "end_to_end_tests", - "version": "1.19.0", + "version": "1.20.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "end_to_end_tests", - "version": "1.19.0", + "version": "1.20.0", "devDependencies": { "@playwright/test": "1.48.0", "@types/node": "20.16.11" diff --git a/end_to_end_tests/package.json b/end_to_end_tests/package.json index ad3d60aed..23f199d33 100644 --- a/end_to_end_tests/package.json +++ b/end_to_end_tests/package.json @@ -1,6 +1,6 @@ { "name": "end_to_end_tests", - "version": "1.19.0", + "version": "1.20.0", "private": true, "description": "", "main": "index.js", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e17ca47a5..9f38b0392 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "secobserve", - "version": "1.19.0", + "version": "1.20.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "secobserve", - "version": "1.19.0", + "version": "1.20.0", "license": "BSD-3-Clause", "dependencies": { "@emotion/react": "11.13.3", diff --git a/frontend/package.json b/frontend/package.json index c93298a7f..b18cd087b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "secobserve", - "version": "1.19.0", + "version": "1.20.0", "license": "BSD-3-Clause", "description": "SecObserve is an open source vulnerability management system for software development and cloud environments.", "private": true, diff --git a/so_configuration_sca_current.yml b/so_configuration_sca_current.yml index d840af2fa..024b0c0b3 100644 --- a/so_configuration_sca_current.yml +++ b/so_configuration_sca_current.yml @@ -1,18 +1,18 @@ trivy_image_backend_current: SCANNER: trivy_image - TARGET: "maibornwolff/secobserve-backend:1.19.0" + TARGET: "maibornwolff/secobserve-backend:1.20.0" FURTHER_PARAMETERS: "--pkg-types os" REPORT_NAME: "trivy_backend_image.json" SO_ORIGIN_SERVICE: "backend" - SO_BRANCH_NAME: "1.19.0" + SO_BRANCH_NAME: "1.20.0" trivy_image_frontend_current: SCANNER: trivy_image - TARGET: "maibornwolff/secobserve-frontend:1.19.0" + TARGET: "maibornwolff/secobserve-frontend:1.20.0" FURTHER_PARAMETERS: "--pkg-types os" REPORT_NAME: "trivy_frontend_image.json" SO_ORIGIN_SERVICE: "frontend" - SO_BRANCH_NAME: "1.19.0" + SO_BRANCH_NAME: "1.20.0" trivy_filesystem_backend_current: SCANNER: trivy_filesystem @@ -20,7 +20,7 @@ trivy_filesystem_backend_current: TARGET: "backend/poetry.lock" REPORT_NAME: "trivy_backend_poetry.json" SO_ORIGIN_SERVICE: "backend" - SO_BRANCH_NAME: "1.19.0" + SO_BRANCH_NAME: "1.20.0" trivy_filesystem_frontend_current: SCANNER: trivy_filesystem @@ -28,7 +28,7 @@ trivy_filesystem_frontend_current: TARGET: "frontend/package-lock.json" REPORT_NAME: "trivy_frontend_npm.json" SO_ORIGIN_SERVICE: "frontend" - SO_BRANCH_NAME: "1.19.0" + SO_BRANCH_NAME: "1.20.0" importer: SO_UPLOAD: "true"