From ef8384b00a88ae7e5d7767a7d37b7a6932acaac3 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 20 Dec 2023 13:33:18 +1100 Subject: [PATCH 0001/1116] Use COPY instead of ADD to follow best practices --- Dockerfile.nitro.builder | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index 7bd8fe2d2..55c481049 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -13,9 +13,9 @@ RUN curl https://sh.rustup.rs -sSf | sh -s -- -y ENV PATH="/root/.cargo/bin:${PATH}" WORKDIR /build -ADD conf ./conf -ADD src ./src -ADD static ./static +COPY conf ./conf +COPY src ./src +COPY static ./static COPY ./pom.xml ./pom.xml # build operator jar and save package version From 980a51da35023983ce2a3f9f6d3569044f693f33 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 20 Dec 2023 14:12:56 +1100 Subject: [PATCH 0002/1116] Copy default-config.conf from scripts/aws/conf/default-config.json This works by explicitly copying the required config files into `build/conf`. Previously we were including all files from `conf` into `build/conf`. This meant: - We were accidentally including `conf/default-config.json` instead of `scripts/aws/conf/default-config.json`. - We had to include extra code to overwrite `build/conf/logback.loki.xml` (from `conf/logback.loki.xml`) with `scripts/aws/conf/logback.loki.xml` - We were including files not required by private operator (e.g. `local-e2e-public-config.json`) --- Dockerfile.nitro.builder | 1 - Makefile.nitro | 17 +++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index 55c481049..eaca75f74 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -13,7 +13,6 @@ RUN curl https://sh.rustup.rs -sSf | sh -s -- -y ENV PATH="/root/.cargo/bin:${PATH}" WORKDIR /build -COPY conf ./conf COPY src ./src COPY static ./static COPY ./pom.xml ./pom.xml diff --git a/Makefile.nitro b/Makefile.nitro index 227f50d3b..70ed5e0f1 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -35,11 +35,11 @@ clean: build_eif: uid2operator.eif euidoperator.eif -euidoperator.eif: build_artifacts loki_override build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py +euidoperator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; cd build; nitro-cli build-enclave --docker-uri euidoperator --output-file euidoperator.eif -uid2operator.eif: build_artifacts loki_override build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py +uid2operator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; cd build; nitro-cli build-enclave --docker-uri uid2operator --output-file uid2operator.eif @@ -49,7 +49,10 @@ build/load_config.py: ./scripts/aws/load_config.py build/make_config.py: ./scripts/aws/make_config.py cp ./scripts/aws/make_config.py ./build/ -build/configs: build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json +build/configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.loki.xml + +build/conf/default-config.json: build_artifacts ./scripts/aws/conf/default-config.json + cp ./scripts/aws/conf/default-config.json ./build/conf/default-config.json build/conf/prod-uid2-config.json: build_artifacts ./scripts/aws/conf/prod-uid2-config.json cp ./scripts/aws/conf/prod-uid2-config.json ./build/conf/prod-uid2-config.json @@ -63,11 +66,8 @@ build/conf/integ-uid2-config.json: build_artifacts ./scripts/aws/conf/integ-uid2 build/conf/integ-euid-config.json: build_artifacts ./scripts/aws/conf/integ-euid-config.json cp ./scripts/aws/conf/integ-euid-config.json ./build/conf/integ-euid-config.json -loki_override: build/loki_override.stamp - -build/loki_override.stamp build/conf/logback.loki.xml: ./scripts/aws/conf/logback.loki.xml - cp ./scripts/aws/conf/logback.loki.xml build/conf/ - touch ./build/loki_override.stamp +build/conf/logback.loki.xml: ./scripts/aws/conf/logback.loki.xml + cp ./scripts/aws/conf/logback.loki.xml build/conf/logback.loki.xml build/Dockerfile: build_artifacts ./scripts/aws/Dockerfile cp ./scripts/aws/Dockerfile ./build/ @@ -85,6 +85,7 @@ build/build_artifacts.stamp build/vsockpx build/libjnsm.so: Dockerfile.nitro.bui docker create --name uid2-nitro-builder uid2-nitro-builder docker cp uid2-nitro-builder:/build . docker rm uid2-nitro-builder + mkdir -p build/conf touch build/build_artifacts.stamp .PHONY: install uninstall setup_nitro build_artifacts build_eif loki_override build/configs From 9ced9baef869d95162b7d781479cc830d4b10bdb Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 22 Dec 2023 16:10:28 +0800 Subject: [PATCH 0003/1116] Renamed image_details to image-details --- .github/workflows/publish-all-operators.yaml | 4 ++-- .../workflows/publish-public-operator-docker-image.yaml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 4577e56fa..72408ed0d 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -100,7 +100,7 @@ jobs: - name: Download public artifacts uses: actions/download-artifact@v3 with: - name: image_details + name: image-details path: ./artifacts/public_operator - name: Download GCP artifacts @@ -119,7 +119,7 @@ jobs: uses: geekyeggo/delete-artifact@v2 with: name: | - image_details + image-details gcp-oidc-deployment-files azure-cc-deployment-files diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 37dff553f..839451afc 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -59,13 +59,13 @@ jobs: steps: - name: Collect artifacts run: | - mkdir -p image_details + mkdir -p image-details IMAGE_TAG=${{ needs.image.outputs.image_tag }} IMAGE=$(jq -n --arg img "$IMAGE_TAG" '{image_tag: $img}') - echo $IMAGE > image_details/image.json + echo $IMAGE > image-details/image.json - name: Upload artifacts uses: actions/upload-artifact@v3 with: - name: image_details - path: image_details/ + name: image-details + path: image-details/ From eb0412ccfd1b11795f2fcc2972f50824644325e0 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 22 Dec 2023 16:49:34 +0800 Subject: [PATCH 0004/1116] Added artifact upload to Publish All Operators draft release --- .github/workflows/publish-all-operators.yaml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 72408ed0d..ad44c99fa 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -126,7 +126,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v3 with: - name: operator_release + name: uid2-operator-release-${{ needs.start.outputs.new_version }} path: ./artifacts/ release: @@ -134,6 +134,14 @@ jobs: runs-on: ubuntu-latest needs: [start, collectAllArtifacts] steps: + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=${{ needs.start.outputs.new_version }}- + - name: Build changelog id: changelog uses: mikepenz/release-changelog-builder-action@v3 @@ -141,7 +149,7 @@ jobs: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ needs.start.outputs.new_version }}-\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease attach both UID2 and EUID AWS private operator artifacts here.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease include the UID2 and EUID AWS artifacts into uid2-operator-release-${{ needs.start.outputs.new_version }}.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: @@ -153,3 +161,5 @@ jobs: name: ${{ needs.start.outputs.new_version }} body: ${{ steps.changelog.outputs.changelog }} draft: true + files: | + ./artifacts/uid2-operator-release-${{ needs.start.outputs.new_version }}.zip From 48514cb5b22b3e5f127096a6180565a32dfa7b73 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 22 Dec 2023 16:50:34 +0800 Subject: [PATCH 0005/1116] Added version number input check for publish GCP/Azure pipelines --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 6 +++--- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index e97a7a95d..31fa9400e 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -215,13 +215,13 @@ jobs: ${{ env.ARTIFACTS_OUTPUT_DIR }} - name: Generate release archive - if: ${{ steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} run: | zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - name: Build Changelog id: github_release - if: ${{ steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} uses: mikepenz/release-changelog-builder-action@v3 with: configurationJson: | @@ -233,7 +233,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create Release - if: ${{ steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} uses: softprops/action-gh-release@v1 with: name: ${{ steps.version.outputs.new_version }} diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 8d4ce4a60..185181f58 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -252,13 +252,13 @@ jobs: ${{ env.ARTIFACTS_OUTPUT_DIR }} - name: Generate release archive - if: ${{ steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} run: | zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - name: Build Changelog id: github_release - if: ${{ steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} uses: mikepenz/release-changelog-builder-action@v3 with: configurationJson: | @@ -270,7 +270,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create Release - if: ${{ steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} uses: softprops/action-gh-release@v1 with: name: ${{ steps.version.outputs.new_version }} From 84ab4e3a86045c980c65b686d327a96b608eefeb Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 2 Jan 2024 06:11:08 +0000 Subject: [PATCH 0006/1116] Released Patch version: 5.25.23-c2cb3f8d55 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13c422334..dc99fc18d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.21-ffe0007aa2 + 5.25.23-c2cb3f8d55 UTF-8 From 9bbb9b9a9bae51739c09f83d4827dee1bce369a1 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 2 Jan 2024 14:45:27 +0800 Subject: [PATCH 0007/1116] Updated changelog message --- .github/workflows/publish-all-operators.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index ad44c99fa..fb96a74b4 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -149,7 +149,7 @@ jobs: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease include the UID2 and EUID AWS artifacts into uid2-operator-release-${{ needs.start.outputs.new_version }}.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease add the UID2 and EUID AWS artifacts into uid2-operator-release-${{ needs.start.outputs.new_version }}.zip.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: From 1e83bbd769ccd970433865db65b755931e243e69 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 3 Jan 2024 00:13:57 +0000 Subject: [PATCH 0008/1116] Released Patch version: 5.25.24-84ab4e3a86 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dc99fc18d..5a40c9b4f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.23-c2cb3f8d55 + 5.25.24-84ab4e3a86 UTF-8 From 8b6ed8d0f9207fde6f29103a4b823324310ac895 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 3 Jan 2024 13:45:56 +0800 Subject: [PATCH 0009/1116] Updated release message --- .github/workflows/publish-all-operators.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index fb96a74b4..d2fa2e46a 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -149,7 +149,7 @@ jobs: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease add the UID2 and EUID AWS artifacts into uid2-operator-release-${{ needs.start.outputs.new_version }}.zip.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease download uid2-operator-release-${{ needs.start.outputs.new_version }}.zip, rezip its contents together with UID2 and EUID AWS artifacts, then reupload the ZIP file to this draft.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: From 3f57e74dc85288cb7d7f3ece29c1194217932779 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 3 Jan 2024 14:17:43 +0800 Subject: [PATCH 0010/1116] Fixed YAML layout and changelog message --- .github/workflows/publish-all-operators.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index d2fa2e46a..f452d431b 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -95,7 +95,7 @@ jobs: collectAllArtifacts: name: Collect All Artifacts runs-on: ubuntu-latest - needs: [buildPublic, buildGCP, buildAzure] + needs: [start, buildPublic, buildGCP, buildAzure] steps: - name: Download public artifacts uses: actions/download-artifact@v3 @@ -149,7 +149,7 @@ jobs: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ needs.start.outputs.new_version }}-\n```\n\n## TODO\nPlease download uid2-operator-release-${{ needs.start.outputs.new_version }}.zip, rezip its contents together with UID2 and EUID AWS artifacts, then reupload the ZIP file to this draft.\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.meta.outputs.tags }}\n```\n\n## TODO\nPlease upload the zipped AWS artifacts to this draft. (version_number_input: ${{ needs.start.outputs.new_version }})\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: @@ -161,5 +161,5 @@ jobs: name: ${{ needs.start.outputs.new_version }} body: ${{ steps.changelog.outputs.changelog }} draft: true - files: | - ./artifacts/uid2-operator-release-${{ needs.start.outputs.new_version }}.zip + files: | + ./artifacts/uid2-operator-release-${{ needs.start.outputs.new_version }}.zip From 4ab0fef20f2a4e730137d34a7fa0c91e08f581c0 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Thu, 4 Jan 2024 12:31:28 +1100 Subject: [PATCH 0011/1116] Add `ENFORCE_HTTPS` environment variable (#321) * Add E2E config to set `enforce_https` to false * Set `IS_E2E_TEST` environment variable * Replace `IS_E2E_TEST` with `ENFORCE_HTTPS` environment variable * Update pom version to reflect the latest shared version --- pom.xml | 2 +- scripts/gcp-oidc/Dockerfile | 2 +- scripts/gcp-oidc/entrypoint.sh | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5a40c9b4f..38cbdd9c3 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.0.0-c7abb59c26 + 6.0.10-208e0b52b2 ${project.version} diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 1da22360d..059558fd4 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d -LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL" +LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,ENFORCE_HTTPS" # Install Packages RUN apk update && apk add jq diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index ecd69ea7f..b00f1807a 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -43,6 +43,11 @@ if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONME sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} fi +# -- replace `enforce_https` value to ENFORCE_HTTPS if provided +if [ -n "${ENFORCE_HTTPS}" ]; then + sed -i "s#"enforce_https": true#"enforce_https": ${ENFORCE_HTTPS}#g" ${FINAL_CONFIG} +fi + # -- start operator echo "-- starting java application" java \ From b598898b6906a92bc372addda5d2e12739dc26d9 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 4 Jan 2024 01:39:17 +0000 Subject: [PATCH 0012/1116] Released Patch version: 5.25.30-4ab0fef20f --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 38cbdd9c3..06659aa71 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.24-84ab4e3a86 + 5.25.30-4ab0fef20f UTF-8 From 6dc0ba3471d92450005905ed7807653c40be1b5a Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 8 Jan 2024 09:27:45 +1100 Subject: [PATCH 0013/1116] Change allowed env override to `enforce_https` (#322) --- scripts/gcp-oidc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 059558fd4..6ef85f1d8 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d -LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,ENFORCE_HTTPS" +LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,enforce_https" # Install Packages RUN apk update && apk add jq From c76b4c3456e430ffe276e074747b6c433bab768b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 7 Jan 2024 22:28:42 +0000 Subject: [PATCH 0014/1116] Released Patch version: 5.25.32-6dc0ba3471 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 06659aa71..c1ea691da 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.30-4ab0fef20f + 5.25.32-6dc0ba3471 UTF-8 From 0d78ea9ef2d64eb450820fc59047779420a2a055 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 8 Jan 2024 09:48:32 +1100 Subject: [PATCH 0015/1116] Add `ENFORCE_HTTPS` (#323) --- scripts/gcp-oidc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 6ef85f1d8..837422357 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d -LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,enforce_https" +LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,ENFORCE_HTTPS, enforce_https" # Install Packages RUN apk update && apk add jq From 2864fe75b39e91c567b1a29b80bb9a5f1f8da15b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 7 Jan 2024 22:51:14 +0000 Subject: [PATCH 0016/1116] Released Patch version: 5.25.34-0d78ea9ef2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c1ea691da..101eb205c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.32-6dc0ba3471 + 5.25.34-0d78ea9ef2 UTF-8 From 363ddaa484a9f84d1f131dbe543b80fed03433e0 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 8 Jan 2024 12:50:22 +1100 Subject: [PATCH 0017/1116] Only add env override for `ENABLE_HTTPS` (#324) --- scripts/gcp-oidc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 837422357..059558fd4 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d -LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,ENFORCE_HTTPS, enforce_https" +LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,ENFORCE_HTTPS" # Install Packages RUN apk update && apk add jq From a06b74bb765c2f4a3833bd35b8a41bad5720ca31 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jan 2024 02:11:51 +0000 Subject: [PATCH 0018/1116] Released Patch version: 5.25.36-363ddaa484 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 101eb205c..a871967c4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.34-0d78ea9ef2 + 5.25.36-363ddaa484 UTF-8 From 831ff8e23a23b515e6687f5ae2d4af0a13e29a65 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 8 Jan 2024 16:35:42 +1100 Subject: [PATCH 0019/1116] Add `enforce_https` to integ config (#325) * Add `enforce_https` to integ config * Remove unnecessary cat $FINAL_CONFIG * Use false directly instead of $ENFORCE_HTTPS --- scripts/gcp-oidc/conf/integ-uid2-config.json | 3 ++- scripts/gcp-oidc/entrypoint.sh | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/scripts/gcp-oidc/conf/integ-uid2-config.json b/scripts/gcp-oidc/conf/integ-uid2-config.json index d795c0150..2dd489960 100644 --- a/scripts/gcp-oidc/conf/integ-uid2-config.json +++ b/scripts/gcp-oidc/conf/integ-uid2-config.json @@ -10,5 +10,6 @@ "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", "core_attest_url": "https://core-integ.uidapi.com/attest", "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", - "optout_s3_folder": "uid-optout-integ/" + "optout_s3_folder": "uid-optout-integ/", + "enforce_https": true } diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index b00f1807a..a51e1862b 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -2,6 +2,17 @@ # # This script must be compatible with Ash (provided in eclipse-temurin Docker image) and Bash +# for number/boolean +# https://jqlang.github.io/jq/manual/ +# --argjson foo 123 will bind $foo to 123. +function jq_inplace_update_json() { + local file=$1 + local field=$2 + local value=$3 + jq --argjson v "$value" ".$field = \$v" "$file" > tmp.json && mv tmp.json "$file" +} + + # -- set API tokens if [ -z "${API_TOKEN_SECRET_NAME}" ]; then echo "API_TOKEN_SECRET_NAME cannot be empty" @@ -44,10 +55,13 @@ if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONME fi # -- replace `enforce_https` value to ENFORCE_HTTPS if provided -if [ -n "${ENFORCE_HTTPS}" ]; then - sed -i "s#"enforce_https": true#"enforce_https": ${ENFORCE_HTTPS}#g" ${FINAL_CONFIG} +if [ "${ENFORCE_HTTPS}" == false ]; then + echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" + jq_inplace_update_json $FINAL_CONFIG enforce_https false fi +cat $FINAL_CONFIG + # -- start operator echo "-- starting java application" java \ From 6a0644a8fa1310a9a1d6b31102bd44f9e8251a1b Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 9 Jan 2024 13:03:02 +1100 Subject: [PATCH 0020/1116] UID2-2339 create test pipeline for gcp (#315) * Add `operator_type` as inputs * Use v2 of the shared pipeline * Use `gcp` and `azure` instead of private * Use `kcc-UID2-2339-create-test-pipeline-for-gcp` branch for testing * Add run-name * Fix E2E tests run name * Use v2 version for shared actions --- .../workflows/run-e2e-tests-on-operator.yaml | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index e4e43d1f4..cca20f887 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -1,7 +1,15 @@ name: Run operator E2E tests +run-name: ${{ format('Run {0} operator E2E tests', inputs.operator_type) }} by @${{ github.actor }} on: workflow_dispatch: inputs: + operator_type: + type: choice + description: The type of operator [either public or gcp or azure] + options: + - public + - gcp + - azure operator_image_version: description: The pipeline will run the E2E test with this operator image version type: string @@ -36,6 +44,10 @@ on: default: 'main' workflow_call: inputs: + operator_type: + description: The type of operator [either public or gcp or azure] + type: string + default: 'public' operator_image_version: description: The pipeline will run the E2E test with this operator image version type: string @@ -72,8 +84,9 @@ on: jobs: e2e-test: name: E2E Test - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@v2.7 + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@v2 with: + operator_type: ${{ inputs.operator_type }} operator_image_version: ${{ inputs.operator_image_version }} core_image_version: ${{ inputs.core_image_version }} optout_image_version: ${{ inputs.optout_image_version }} @@ -82,4 +95,7 @@ jobs: optout_branch: ${{ inputs.optout_branch }} admin_branch: ${{ inputs.admin_branch }} operator_branch: ${{ github.ref }} - secrets: inherit \ No newline at end of file + gcp_workload_identity_provider_id: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER_ID }} + gcp_service_account: ${{ vars.GCP_SERVICE_ACCOUNT }} + gcp_project: ${{ vars.GCP_PROJECT }} + secrets: inherit From 47da1eabb8bbb2af97c58a9dae67812f623cfea7 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 9 Jan 2024 16:31:33 +1100 Subject: [PATCH 0021/1116] Add E2E test as a part of the gcp publish pipeline (#326) * Add E2E test as a part of the gcp publish pipeline * Create separate steps for GCP operator release --- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 185181f58..5c9da76d2 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -278,3 +278,13 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip + + e2e: + name: E2E + uses: ./.github/workflows/run-e2e-tests-on-operator.yaml + needs: buildImage + with: + operator_type: gcp + operator_image_version: ${{ needs.buildImage.outputs.image_tag }} + operator_branch: ${{ github.ref }} + secrets: inherit From 2cf51dc22640f6f8b99a7ce1deb2cde84b9270f2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jan 2024 05:32:26 +0000 Subject: [PATCH 0022/1116] Released Patch version: 5.25.40-47da1eabb8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a871967c4..53e7f675c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.36-363ddaa484 + 5.25.40-47da1eabb8 UTF-8 From 564161d43c6c4575cb04fe054c0509c14515e6ae Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 15 Jan 2024 13:37:44 +1100 Subject: [PATCH 0023/1116] Enable CSTG domain name check for E2E public operators --- conf/local-e2e-docker-public-config.json | 2 +- conf/local-e2e-public-config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index 0ce8b1eb7..87b042c7b 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -23,7 +23,7 @@ "identity_scope": "uid2", "enable_v2_encryption": true, "client_side_token_generate": true, - "client_side_token_generate_domain_name_check_enabled": false, + "client_side_token_generate_domain_name_check_enabled": true, "key_sharing_endpoint_provide_site_domain_names": true, "validate_service_links": true, "optout_s3_bucket": "test-optout-bucket", diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index 6fbb12da2..aed23ed8e 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -37,6 +37,6 @@ "optout_max_partitions": 30, "optout_partition_interval": 86400, "client_side_token_generate": true, - "client_side_token_generate_domain_name_check_enabled": false, + "client_side_token_generate_domain_name_check_enabled": true, "key_sharing_endpoint_provide_site_domain_names": true } From f2ad2881b80f1a8ddce1261b0cad64574f77319f Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 16 Jan 2024 13:58:38 +1100 Subject: [PATCH 0024/1116] UID2-2340 Allow override for `enforce_https` (#329) * Allow override for `enforce_https` * Print out FINAL_CONFIG for debugging purpose * Use jq to update json files * Use sed directly * Give Dockerfile same user access as gcp-oidc * Revert change for removing uid2-operator user * Use TMP_FINAL_CONFIG instead of tmp.json --- scripts/azure-cc/conf/integ-uid2-config.json | 3 ++- scripts/azure-cc/deployment/operator.json | 10 ++++++++++ scripts/azure-cc/entrypoint.sh | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/scripts/azure-cc/conf/integ-uid2-config.json b/scripts/azure-cc/conf/integ-uid2-config.json index 2cd4be5c3..77828b385 100644 --- a/scripts/azure-cc/conf/integ-uid2-config.json +++ b/scripts/azure-cc/conf/integ-uid2-config.json @@ -10,5 +10,6 @@ "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", "core_attest_url": "https://core-integ.uidapi.com/attest", "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", - "optout_s3_folder": "uid-optout-integ/" + "optout_s3_folder": "uid-optout-integ/", + "enforce_https": true } diff --git a/scripts/azure-cc/deployment/operator.json b/scripts/azure-cc/deployment/operator.json index 14ab9531d..eb1ae295f 100644 --- a/scripts/azure-cc/deployment/operator.json +++ b/scripts/azure-cc/deployment/operator.json @@ -54,6 +54,12 @@ "metadata": { "description": "Operator Key" } + }, + "enforceHttps": { + "type": "bool", + "metadata": { + "description": "Whether to use HTTPS to communicate with core and optout service" + } } }, "variables": { @@ -118,6 +124,10 @@ { "name": "DEPLOYMENT_ENVIRONMENT", "value": "[parameters('deploymentEnvironment')]" + }, + { + "name": "ENFORCE_HTTPS", + "value": "[parameters('enforceHttps')]" } ] } diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index e5281f3da..fcbaa8d5e 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -2,6 +2,18 @@ # # This script must be compatible with Ash (provided in eclipse-temurin Docker image) and Bash +TMP_FINAL_CONFIG="/tmp/final-config.tmp" + +# for number/boolean +# https://jqlang.github.io/jq/manual/ +# --argjson foo 123 will bind $foo to 123. +function jq_inplace_update_json() { + local file=$1 + local field=$2 + local value=$3 + jq --argjson v "$value" ".$field = \$v" "$file" > $TMP_FINAL_CONFIG && mv $TMP_FINAL_CONFIG "$file" +} + if [ -z "${VAULT_NAME}" ]; then echo "VAULT_NAME cannot be empty" exit 1 @@ -48,6 +60,14 @@ if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONME sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} fi +# -- replace `enforce_https` value to ENFORCE_HTTPS if provided +if [ "${ENFORCE_HTTPS}" == false ]; then + echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" + jq_inplace_update_json $FINAL_CONFIG enforce_https false +fi + +cat $FINAL_CONFIG + # -- start operator echo "-- starting java application" java \ From b49656910377786f0b331c2b6de18eb04db42a88 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 17 Jan 2024 14:02:08 +1100 Subject: [PATCH 0025/1116] UID2-2340 Add test pipeline for Azure (#328) * Add test pipeline for Azure * Pass in azure crendentials * Remove inputs for passing in azure crenditials * Test azure publish workflow on kcc-UID2-2340-add-test-pipeline-for-azure * Move feature branch to v2 tag --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 31fa9400e..05d0f61e9 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -241,3 +241,13 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip + + e2e: + name: E2E + uses: ./.github/workflows/run-e2e-tests-on-operator.yaml + needs: buildImage + with: + operator_type: azure + operator_image_version: ${{ needs.buildImage.outputs.image_tag }} + operator_branch: ${{ github.ref }} + secrets: inherit From d5777feead741dc95968726739065d782fc03271 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Jan 2024 03:14:28 +0000 Subject: [PATCH 0026/1116] Released Patch version: 5.25.45-b496569103 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 53e7f675c..749f8048c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.40-47da1eabb8 + 5.25.45-b496569103 UTF-8 From 046f368a0c7fa9d2bbe0c866b4c8489dc58d67ba Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 17 Jan 2024 13:46:53 +0800 Subject: [PATCH 0027/1116] Added key ID in invalid refresh key log --- .../java/com/uid2/operator/service/V2RequestUtil.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/V2RequestUtil.java b/src/main/java/com/uid2/operator/service/V2RequestUtil.java index 878358a8b..16f4347a7 100644 --- a/src/main/java/com/uid2/operator/service/V2RequestUtil.java +++ b/src/main/java/com/uid2/operator/service/V2RequestUtil.java @@ -129,15 +129,15 @@ public static V2Request parseRefreshRequest(String bodyString, KeyManager keyMan KeysetKey key = keyManager.getKey(keyId); if (key == null) { - return new V2Request("Invalid key: Generator of this token does not exist."); + return new V2Request(String.format("Invalid key: Generator of this token (Key ID: %d) does not exist.", keyId)); } byte[] decrypted; try { decrypted = AesGcm.decrypt(bytes, 5, key); } catch (Exception ex) { - LOGGER.error("Invalid data: Check encryption method and encryption key", ex); - return new V2Request("Invalid data: Check encryption method and encryption key"); + LOGGER.error("Invalid data: Check encryption method and encryption key.", ex); + return new V2Request("Invalid data: Check encryption method and encryption key."); } try { @@ -147,8 +147,8 @@ public static V2Request parseRefreshRequest(String bodyString, KeyManager keyMan return new V2Request(null, refreshToken, responseKey); } catch (Exception ex) { - LOGGER.error("Invalid format: Payload is not valid json or missing required data", ex); - return new V2Request("Invalid format: Payload is not valid json or missing required data"); + LOGGER.error("Invalid format: Payload is not valid json or missing required data.", ex); + return new V2Request("Invalid format: Payload is not valid json or missing required data."); } } From dfcf9c51f11da6d884398fbeed8c36a2e7d6f681 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Jan 2024 08:26:53 +0000 Subject: [PATCH 0028/1116] [CI Pipeline] Released Snapshot version: 5.25.45-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 53e7f675c..e1561a31d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.40-47da1eabb8 + 5.25.45-SNAPSHOT UTF-8 From 753482e9c21e9abd166eb61895cc23fdee6a09f6 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 17 Jan 2024 17:28:06 +0800 Subject: [PATCH 0029/1116] Updated Dockerfile formatting --- scripts/aws/Dockerfile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 36ed33f0e..11e5358c8 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -18,19 +18,19 @@ RUN apt update -y \ RUN pip3 install boto3==1.16.9 COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar -COPY ./static /app/static -COPY ./vsockpx /app/ -COPY ./libjnsm.so /app/lib/ -COPY ./load_config.py /app/ -COPY ./make_config.py /app/ -COPY ./entrypoint.sh /app/ +COPY ./static /app/static +COPY ./vsockpx /app/ +COPY ./libjnsm.so /app/lib/ +COPY ./load_config.py /app/ +COPY ./make_config.py /app/ +COPY ./entrypoint.sh /app/ COPY ./proxies.nitro.yaml /app/ -COPY ./conf/default-config.json /app/conf/ -COPY conf/prod-uid2-config.json /app/conf/prod-uid2-config.json -COPY conf/integ-uid2-config.json /app/conf/integ-uid2-config.json -COPY ./conf/prod-euid-config.json /app/conf/prod-euid-config.json +COPY ./conf/default-config.json /app/conf/ +COPY ./conf/prod-uid2-config.json /app/conf/prod-uid2-config.json +COPY ./conf/integ-uid2-config.json /app/conf/integ-uid2-config.json +COPY ./conf/prod-euid-config.json /app/conf/prod-euid-config.json COPY ./conf/integ-euid-config.json /app/conf/integ-euid-config.json -COPY ./conf/*.xml /app/conf/ +COPY ./conf/*.xml /app/conf/ RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh From f7d8e654a87fd2d661a222536e07d53281734381 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 17 Jan 2024 17:29:25 +0800 Subject: [PATCH 0030/1116] Updated aws entrypoint.sh formatting --- scripts/aws/entrypoint.sh | 52 +++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 073eaf8a2..0757f41f0 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -1,63 +1,79 @@ #!/bin/bash -euf set -o pipefail - ulimit -n 65536 -# setup loopback device +# -- setup loopback device +echo "Setting up loopback device..." + ifconfig lo 127.0.0.1 # -- start vsock proxy +echo "Starting vsock proxy..." + /app/vsockpx --config /app/proxies.nitro.yaml --daemon --workers $(( $(nproc) * 2 )) --log-level 3 -# -- load config via proxy -if [ "$IDENTITY_SCOPE" = 'UID2' ]; then - UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo ${BASH_REMATCH[1]} || echo "uid2-operator-config-key") -elif [ "$IDENTITY_SCOPE" = 'EUID' ]; then - UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo ${BASH_REMATCH[1]} || echo "euid-operator-config-key") +# -- load env vars via proxy +echo "Loading env vars via proxy..." + +if [ "${IDENTITY_SCOPE}" = 'UID2' ]; then + UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") +elif [ "${IDENTITY_SCOPE}" = 'EUID' ]; then + UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") else - echo "Unrecognized IDENTITY_SCOPE $IDENTITY_SCOPE" + echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" exit 1 fi +echo "UID2_CONFIG_SECRET_KEY=${UID2_CONFIG_SECRET_KEY}" + export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r '.region') +echo "AWS_REGION_NAME=${AWS_REGION_NAME}" +echo "127.0.0.1 secretsmanager.${AWS_REGION_NAME}.amazonaws.com" >> /etc/hosts + IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/iam/security-credentials/) echo "IAM_ROLE=$IAM_ROLE" + CREDS_ENDPOINT="http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE" export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 $CREDS_ENDPOINT | jq -r '.AccessKeyId') export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 $CREDS_ENDPOINT | jq -r '.SecretAccessKey') export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 $CREDS_ENDPOINT | jq -r '.Token') -echo "UID2_CONFIG_SECRET_KEY=$UID2_CONFIG_SECRET_KEY" -echo "AWS_REGION_NAME=$AWS_REGION_NAME" -echo "127.0.0.1 secretsmanager.$AWS_REGION_NAME.amazonaws.com" >> /etc/hosts -python3 /app/load_config.py >/app/conf/config-overrides.json +# -- load configs via proxy +echo "Loading config overrides..." +export OVERRIDES_CONFIG="/app/conf/config-overrides.json" +python3 /app/load_config.py > ${OVERRIDES_CONFIG} +echo "Loading config final..." +export FINAL_CONFIG="/app/conf/config-final.json" if [ "$IDENTITY_SCOPE" = 'UID2' ]; then - python3 /app/make_config.py /app/conf/prod-uid2-config.json /app/conf/integ-uid2-config.json /app/conf/config-overrides.json $(nproc) >/app/conf/config-final.json + python3 /app/make_config.py /app/conf/prod-uid2-config.json /app/conf/integ-uid2-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} elif [ "$IDENTITY_SCOPE" = 'EUID' ]; then - python3 /app/make_config.py /app/conf/prod-euid-config.json /app/conf/integ-euid-config.json /app/conf/config-overrides.json $(nproc) >/app/conf/config-final.json + python3 /app/make_config.py /app/conf/prod-euid-config.json /app/conf/integ-euid-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} else echo "Unrecognized IDENTITY_SCOPE $IDENTITY_SCOPE" exit 1 fi get_config_value() { - jq -r ".\"$1\"" /app/conf/config-final.json + jq -r ".\"$1\"" ${FINAL_CONFIG} } -echo "-- setup loki" +# -- setup loki +echo "Setting up Loki..." + [[ "$(get_config_value 'loki_enabled')" == "true" ]] \ && SETUP_LOKI_LINE="-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dlogback.configurationFile=./conf/logback.loki.xml" \ || SETUP_LOKI_LINE="" HOSTNAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/local-hostname) -echo "HOSTNAME=$HOSTNAME" +echo "HOSTNAME=${HOSTNAME}" # -- set pwd to /app so we can find default configs cd /app -echo "-- starting java application" # -- start operator +echo "Starting Java application..." + java \ -XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \ -Djava.security.egd=file:/dev/./urandom \ From 7a11c3aad4678d52a35e56ec221efc34fbe1df80 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 17 Jan 2024 17:29:59 +0800 Subject: [PATCH 0031/1116] Updated URL and HTTPS override for AWS --- scripts/aws/entrypoint.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 0757f41f0..77731e29e 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -58,6 +58,21 @@ get_config_value() { jq -r ".\"$1\"" ${FINAL_CONFIG} } +# -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided +# -- using hardcoded domains is fine because they should not be changed frequently +if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ]; then + echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..." + + sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} + sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} +fi + +# -- replace `enforce_https` value to ENFORCE_HTTPS if provided +if [ "${ENFORCE_HTTPS}" == false ]; then + echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" + jq_inplace_update_json ${FINAL_CONFIG} enforce_https false +fi + # -- setup loki echo "Setting up Loki..." From f908234e6924863a5ece41af11d0b61c1b204239 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 17 Jan 2024 17:36:09 +0800 Subject: [PATCH 0032/1116] Updated aws entrypoint.sh formatting --- scripts/aws/entrypoint.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 77731e29e..46e8c5f77 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -5,12 +5,10 @@ ulimit -n 65536 # -- setup loopback device echo "Setting up loopback device..." - ifconfig lo 127.0.0.1 # -- start vsock proxy echo "Starting vsock proxy..." - /app/vsockpx --config /app/proxies.nitro.yaml --daemon --workers $(( $(nproc) * 2 )) --log-level 3 # -- load env vars via proxy @@ -45,12 +43,12 @@ python3 /app/load_config.py > ${OVERRIDES_CONFIG} echo "Loading config final..." export FINAL_CONFIG="/app/conf/config-final.json" -if [ "$IDENTITY_SCOPE" = 'UID2' ]; then +if [ "${IDENTITY_SCOPE}" = 'UID2' ]; then python3 /app/make_config.py /app/conf/prod-uid2-config.json /app/conf/integ-uid2-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} -elif [ "$IDENTITY_SCOPE" = 'EUID' ]; then +elif [ "${IDENTITY_SCOPE}" = 'EUID' ]; then python3 /app/make_config.py /app/conf/prod-euid-config.json /app/conf/integ-euid-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} else - echo "Unrecognized IDENTITY_SCOPE $IDENTITY_SCOPE" + echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" exit 1 fi @@ -75,7 +73,6 @@ fi # -- setup loki echo "Setting up Loki..." - [[ "$(get_config_value 'loki_enabled')" == "true" ]] \ && SETUP_LOKI_LINE="-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dlogback.configurationFile=./conf/logback.loki.xml" \ || SETUP_LOKI_LINE="" @@ -88,7 +85,6 @@ cd /app # -- start operator echo "Starting Java application..." - java \ -XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \ -Djava.security.egd=file:/dev/./urandom \ From fd362c1bb0d49ba6a7f1581613905467287fd1e8 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 17 Jan 2024 18:26:43 +0800 Subject: [PATCH 0033/1116] Added override URL env vars in AWS Dockerfile --- scripts/aws/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 11e5358c8..e57b7ba84 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -1,16 +1,21 @@ FROM openjdk:11.0-jre-slim-bullseye WORKDIR /app + ARG JAR_NAME=uid2-operator ARG JAR_VERSION=1.0.0 ARG IMAGE_VERSION=1.0.0.unknownhash ARG IDENTITY_SCOPE=UID2 + ENV JAR_NAME=${JAR_NAME} ENV JAR_VERSION=${JAR_VERSION} ENV IMAGE_VERSION=${IMAGE_VERSION} ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} ENV ENCLAVE_ENVIRONMENT=aws-nitro ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" +ENV OPTOUT_BASE_URL="" +ENV OPTOUT_BASE_URL="" +ENV ENFORCE_HTTPS="true" RUN apt update -y \ && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip \ From c769fe2d94256a07e1fe1764d73d3da6b68f7a9f Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Jan 2024 10:19:01 +1100 Subject: [PATCH 0034/1116] Update shared to allow enforceJWT --- pom.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 53e7f675c..a61616f9a 100644 --- a/pom.xml +++ b/pom.xml @@ -22,10 +22,19 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.0.10-208e0b52b2 + 6.0.14-SNAPSHOT ${project.version} + + + snapshots-repo + https://s01.oss.sonatype.org/content/repositories/snapshots + false + true + + + com.google.guava From e01a3d2966851ad73fa7d1160cf2dde925f44889 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Jan 2024 23:23:12 +0000 Subject: [PATCH 0035/1116] [CI Pipeline] Released Snapshot version: 5.25.45-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a61616f9a..f504c9ca8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.40-47da1eabb8 + 5.25.45-SNAPSHOT UTF-8 From 232b7e1586b9fa1716974649f0df825a60d41305 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Jan 2024 14:41:24 +1100 Subject: [PATCH 0036/1116] Bump build number --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index f504c9ca8..deffcf624 100644 --- a/pom.xml +++ b/pom.xml @@ -362,3 +362,4 @@ + From eaf009634191cf93795769e2227d16b6bc6426d6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 18 Jan 2024 03:44:51 +0000 Subject: [PATCH 0037/1116] [CI Pipeline] Released Snapshot version: 5.25.47-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index deffcf624..1c61d96a9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.45-SNAPSHOT + 5.25.47-SNAPSHOT UTF-8 From e85b210bc3099e2a050b169652b539fff6b53885 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 18 Jan 2024 14:41:04 +0800 Subject: [PATCH 0038/1116] Removed env var args from AWS Dockerfile --- scripts/aws/Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index e57b7ba84..253826995 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -13,9 +13,6 @@ ENV IMAGE_VERSION=${IMAGE_VERSION} ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} ENV ENCLAVE_ENVIRONMENT=aws-nitro ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" -ENV OPTOUT_BASE_URL="" -ENV OPTOUT_BASE_URL="" -ENV ENFORCE_HTTPS="true" RUN apt update -y \ && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip \ From 97f01c7223b5cb849d8c615d87f4457857e74505 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 18 Jan 2024 14:50:33 +0800 Subject: [PATCH 0039/1116] Added deployment env check for AWS script --- scripts/aws/entrypoint.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 46e8c5f77..7a16e9558 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -41,6 +41,16 @@ echo "Loading config overrides..." export OVERRIDES_CONFIG="/app/conf/config-overrides.json" python3 /app/load_config.py > ${OVERRIDES_CONFIG} +export DEPLOYMENT_ENVIRONMENT=$(jq -r '.environment' < ${OVERRIDES_CONFIG}) +if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then + echo "DEPLOYMENT_ENVIRONMENT cannot be empty" + exit 1 +fi +if [ "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ] && [ "${DEPLOYMENT_ENVIRONMENT}" != 'integ' ]; then + echo "Unrecognized DEPLOYMENT_ENVIRONMENT ${DEPLOYMENT_ENVIRONMENT}" + exit 1 +fi + echo "Loading config final..." export FINAL_CONFIG="/app/conf/config-final.json" if [ "${IDENTITY_SCOPE}" = 'UID2' ]; then @@ -58,16 +68,15 @@ get_config_value() { # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently -if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ]; then +if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..." - sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} fi # -- replace `enforce_https` value to ENFORCE_HTTPS if provided -if [ "${ENFORCE_HTTPS}" == false ]; then - echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" +if [ "${ENFORCE_HTTPS}" == false ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then + echo "Replacing enforce_https by ${ENFORCE_HTTPS}..." jq_inplace_update_json ${FINAL_CONFIG} enforce_https false fi From 3b13279a5cd82fe755bfc792439830b5f8f046dd Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 18 Jan 2024 14:56:24 +0800 Subject: [PATCH 0040/1116] Updated AWS script formatting --- scripts/aws/entrypoint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 7a16e9558..fde5364a3 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -99,6 +99,6 @@ java \ -Djava.security.egd=file:/dev/./urandom \ -Djava.library.path=/app/lib \ -Dvertx-config-path=/app/conf/config-final.json \ - $SETUP_LOKI_LINE \ + "$SETUP_LOKI_LINE" \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ - -jar /app/$JAR_NAME-$JAR_VERSION.jar + -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar From 6bb7d3630f1b93410b1db685e0584ec7c77aaea8 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 19 Jan 2024 11:38:51 +1100 Subject: [PATCH 0041/1116] Set ad token v4 percentage to 0 for private operators --- scripts/aws/conf/default-config.json | 2 +- scripts/azure-cc/conf/default-config.json | 2 +- scripts/gcp-oidc/conf/default-config.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/aws/conf/default-config.json b/scripts/aws/conf/default-config.json index 97548b456..4146e55c0 100644 --- a/scripts/aws/conf/default-config.json +++ b/scripts/aws/conf/default-config.json @@ -34,5 +34,5 @@ "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, "validate_service_links": false, - "advertising_token_v4_percentage": 100 + "advertising_token_v4_percentage": 0 } diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index 6092c8b7b..0464ed92d 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -39,5 +39,5 @@ "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, "validate_service_links": false, - "advertising_token_v4_percentage": 100 + "advertising_token_v4_percentage": 0 } diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index 423a7af34..91a1b38e6 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -39,5 +39,5 @@ "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, "validate_service_links": false, - "advertising_token_v4_percentage": 100 + "advertising_token_v4_percentage": 0 } From a5e9c0b6886b0ab67f5c94346494c117a20262a1 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 22 Jan 2024 11:53:33 +1100 Subject: [PATCH 0042/1116] Removed invalid test --- pom.xml | 10 +++++++++- .../com/uid2/operator/store/OptOutCloudStorage.java | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1c61d96a9..242e4e791 100644 --- a/pom.xml +++ b/pom.xml @@ -22,9 +22,17 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.0.14-SNAPSHOT + 6.0.18-SNAPSHOT ${project.version} + + + snapshots-repo + https://s01.oss.sonatype.org/content/repositories/snapshots + false + true + + diff --git a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java index 9aa60d19e..3c5d2f269 100644 --- a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java +++ b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java @@ -5,6 +5,8 @@ import com.uid2.shared.cloud.CloudStorageException; import com.uid2.shared.cloud.URLStorageWithMetadata; import com.uid2.shared.optout.OptOutMetadata; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; @@ -28,7 +30,7 @@ public OptOutCloudStorage(UidOptOutClient uidOptOutClient, String metadataPath, @Override protected List extractListFromMetadata() throws CloudStorageException { - try (InputStream input = this.uidOptOutClient.downloadFromOptOut(metadataPath)) { + try (InputStream input = this.uidOptOutClient.download(metadataPath)) { OptOutMetadata m = OptOutMetadata.fromJsonString(Utils.readToEnd(input)); return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); } catch (IOException e) { From 179da17b477845515d8830b4961a17ee23ca0bdc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 22 Jan 2024 12:04:50 +1100 Subject: [PATCH 0043/1116] Update version of shared --- pom.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 242e4e791..79dc648b5 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.0.18-SNAPSHOT + 6.0.20-SNAPSHOT ${project.version} @@ -34,14 +34,6 @@ - - - snapshots-repo - https://s01.oss.sonatype.org/content/repositories/snapshots - false - true - - From d2ae752416224773227e029fdc1adf748b039847 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 22 Jan 2024 01:07:19 +0000 Subject: [PATCH 0044/1116] [CI Pipeline] Released Snapshot version: 5.25.52-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 79dc648b5..3391f1a9b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.47-SNAPSHOT + 5.25.52-SNAPSHOT UTF-8 From 2d8ae6fbead83bd74fca709ec949b6d96bb7cd4f Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 22 Jan 2024 14:50:38 +1100 Subject: [PATCH 0045/1116] Updated shared version --- pom.xml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 3391f1a9b..f2220612c 100644 --- a/pom.xml +++ b/pom.xml @@ -22,18 +22,9 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.0.20-SNAPSHOT + 6.1.0-649c2e7609 ${project.version} - - - snapshots-repo - https://s01.oss.sonatype.org/content/repositories/snapshots - false - true - - - From fc9d75fdb40ae2a60e0bc3aa3a7b1963722c9fe6 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 22 Jan 2024 14:53:17 +1100 Subject: [PATCH 0046/1116] Remove unnecessary imports --- src/main/java/com/uid2/operator/store/OptOutCloudStorage.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java index 3c5d2f269..fdc76051a 100644 --- a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java +++ b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java @@ -5,8 +5,6 @@ import com.uid2.shared.cloud.CloudStorageException; import com.uid2.shared.cloud.URLStorageWithMetadata; import com.uid2.shared.optout.OptOutMetadata; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; From ad514cfce50425f885b8d4944e65606f5f1a08e2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 22 Jan 2024 04:04:05 +0000 Subject: [PATCH 0047/1116] [CI Pipeline] Released Patch version: 5.25.56-5cb84da6f1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f2220612c..6955d8f53 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.52-SNAPSHOT + 5.25.56-5cb84da6f1 UTF-8 From 3a1ac55187330a0923e183dfb3ff465129ed5a2a Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 22 Jan 2024 20:01:56 +0800 Subject: [PATCH 0048/1116] Updated E2E pipeline inputs --- .../workflows/run-e2e-tests-on-operator.yaml | 83 ++++++++++++------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index cca20f887..7a62ee14a 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -1,90 +1,114 @@ name: Run operator E2E tests run-name: ${{ format('Run {0} operator E2E tests', inputs.operator_type) }} by @${{ github.actor }} + on: workflow_dispatch: inputs: operator_type: type: choice - description: The type of operator [either public or gcp or azure] + description: The operator type [public, gcp, azure, aws] options: - public - gcp - azure + - aws operator_image_version: description: The pipeline will run the E2E test with this operator image version type: string - default: 'latest' + default: latest core_image_version: description: The pipeline will run the E2E test with this core image version type: string - default: 'latest' + default: latest optout_image_version: description: The pipeline will run the E2E test with this optout image version type: string - default: 'latest' + default: latest e2e_image_version: description: The pipeline will run the E2E test with this e2e image version type: string - default: 'latest' + default: latest core_branch: - description: 'The branch of UID2-core to test on' + description: The branch of uid2-core to test on type: string - default: 'main' + default: main optout_branch: - description: 'The branch of UID2-optout to test on' + description: The branch of uid2-optout to test on type: string - default: 'main' + default: main admin_branch: - description: 'The branch of UID2-admin to test on' + description: The branch of uid2-admin to test on type: string - default: 'main' + default: main operator_branch: - description: 'The branch of UID2-operator to test on' + description: The branch of uid2-operator to test on + type: string + default: main + aws_region: + description: The AWS region [us-east-1, us-west-1, ca-central-1] + type: string + aws_ami: + description: The AWS AMI ID + type: string + aws_pcr0: + description: The AWS PCR0 type: string - default: 'main' + workflow_call: inputs: operator_type: - description: The type of operator [either public or gcp or azure] + description: The operator type [public, gcp, azure, aws] type: string - default: 'public' + default: public operator_image_version: description: The pipeline will run the E2E test with this operator image version type: string - default: 'latest' + default: latest core_image_version: description: The pipeline will run the E2E test with this core image version type: string - default: 'latest' + default: latest optout_image_version: description: The pipeline will run the E2E test with this optout image version type: string - default: 'latest' + default: latest e2e_image_version: description: The pipeline will run the E2E test with this e2e image version type: string - default: 'latest' + default: latest core_branch: - description: 'The branch of UID2-core to test on' + description: The branch of uid2-core to test on type: string - default: 'main' + default: main optout_branch: - description: 'The branch of UID2-optout to test on' + description: The branch of uid2-optout to test on type: string - default: 'main' + default: main admin_branch: - description: 'The branch of UID2-admin to test on' + description: The branch of uid2-admin to test on type: string - default: 'main' + default: main operator_branch: - description: 'The branch of UID2-operator to test on' + description: The branch of uid2-operator to test on + type: string + default: main + aws_region: + description: The AWS region [us-east-1, us-west-1, ca-central-1] + type: string + default: us-east-1 + aws_ami: + description: The AWS AMI ID + type: string + default: '' + aws_pcr0: + description: The AWS PCR0 type: string - default: 'main' + default: '' jobs: e2e-test: name: E2E Test - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@v2 + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@gdm-UID2-2341-aws-test-pipeline with: operator_type: ${{ inputs.operator_type }} operator_image_version: ${{ inputs.operator_image_version }} @@ -98,4 +122,7 @@ jobs: gcp_workload_identity_provider_id: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER_ID }} gcp_service_account: ${{ vars.GCP_SERVICE_ACCOUNT }} gcp_project: ${{ vars.GCP_PROJECT }} + aws_region: ${{ inputs.aws_region }} + aws_ami: ${{ inputs.aws_ami }} + aws_pcr0: ${{ inputs.aws_pcr0 }} secrets: inherit From c4fbd41c63a856be1d977412da4ad2409cdb0e28 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 22 Jan 2024 20:04:00 +0800 Subject: [PATCH 0049/1116] Fixed formatting --- .github/workflows/run-e2e-tests-on-operator.yaml | 1 - scripts/aws/entrypoint.sh | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 7a62ee14a..60526ae66 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -1,6 +1,5 @@ name: Run operator E2E tests run-name: ${{ format('Run {0} operator E2E tests', inputs.operator_type) }} by @${{ github.actor }} - on: workflow_dispatch: inputs: diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index fde5364a3..0385487f1 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -14,9 +14,9 @@ echo "Starting vsock proxy..." # -- load env vars via proxy echo "Loading env vars via proxy..." -if [ "${IDENTITY_SCOPE}" = 'UID2' ]; then +if [ "${IDENTITY_SCOPE}" = "UID2" ]; then UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") -elif [ "${IDENTITY_SCOPE}" = 'EUID' ]; then +elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") else echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" From 0ccd7d20179fcdd86ce9dac2afce89522bd8354d Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 22 Jan 2024 22:26:50 +0800 Subject: [PATCH 0050/1116] Changed AWS args input --- .../workflows/run-e2e-tests-on-operator.yaml | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 60526ae66..1a81accf7 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -43,15 +43,14 @@ on: description: The branch of uid2-operator to test on type: string default: main - aws_region: - description: The AWS region [us-east-1, us-west-1, ca-central-1] - type: string - aws_ami: - description: The AWS AMI ID - type: string - aws_pcr0: - description: The AWS PCR0 - type: string + aws: + description: The arguments for AWS private operator + type: string + default: '{ + "region": "us-east-1", + "ami": "ami-xxxxx", + "pcr0": "xxxxx" + }' workflow_call: inputs: @@ -91,18 +90,14 @@ on: description: The branch of uid2-operator to test on type: string default: main - aws_region: - description: The AWS region [us-east-1, us-west-1, ca-central-1] - type: string - default: us-east-1 - aws_ami: - description: The AWS AMI ID - type: string - default: '' - aws_pcr0: - description: The AWS PCR0 - type: string - default: '' + aws: + description: The arguments for AWS private operator + type: string + default: '{ + "region": "us-east-1", + "ami": "ami-xxxxx", + "pcr0": "xxxxx" + }' jobs: e2e-test: @@ -121,7 +116,7 @@ jobs: gcp_workload_identity_provider_id: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER_ID }} gcp_service_account: ${{ vars.GCP_SERVICE_ACCOUNT }} gcp_project: ${{ vars.GCP_PROJECT }} - aws_region: ${{ inputs.aws_region }} - aws_ami: ${{ inputs.aws_ami }} - aws_pcr0: ${{ inputs.aws_pcr0 }} + aws_region: ${{ fromJson(inputs.aws).region }} + aws_ami: ${{ fromJson(inputs.aws).ami }} + aws_pcr0: ${{ fromJson(inputs.aws).pcr0 }} secrets: inherit From e8653dda98a2fbd48f761505cd9e1e5def266264 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 22 Jan 2024 22:54:47 +0800 Subject: [PATCH 0051/1116] Updated YAML indentation --- .github/workflows/run-e2e-tests-on-operator.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 1a81accf7..c5f67021f 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -49,8 +49,8 @@ on: default: '{ "region": "us-east-1", "ami": "ami-xxxxx", - "pcr0": "xxxxx" - }' + "pcr0": "xxxxx" + }' workflow_call: inputs: @@ -97,7 +97,7 @@ on: "region": "us-east-1", "ami": "ami-xxxxx", "pcr0": "xxxxx" - }' + }' jobs: e2e-test: From cf1f44e4714b0a1f1f475eda49bbffe3a4ea598e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 23 Jan 2024 11:00:50 +0800 Subject: [PATCH 0052/1116] Updated required args and pipeline name for E2E tests --- .github/workflows/run-e2e-tests-on-operator.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index c5f67021f..236f8c5c3 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -1,11 +1,12 @@ -name: Run operator E2E tests -run-name: ${{ format('Run {0} operator E2E tests', inputs.operator_type) }} by @${{ github.actor }} +name: Run Operator E2E Tests +run-name: ${{ format('Run {0} Operator E2E Tests', inputs.operator_type) }} by @${{ github.actor }} on: workflow_dispatch: inputs: operator_type: - type: choice description: The operator type [public, gcp, azure, aws] + required: true + type: choice options: - public - gcp From 22702f26cae5c65a0642ee4b4021b3623a0762b0 Mon Sep 17 00:00:00 2001 From: Cody Constine Date: Wed, 24 Jan 2024 08:34:38 -0700 Subject: [PATCH 0053/1116] Adding the token expiration time change --- scripts/aws/conf/prod-euid-config.json | 2 +- scripts/aws/conf/prod-uid2-config.json | 2 +- scripts/azure-cc/conf/prod-uid2-config.json | 3 ++- scripts/gcp-oidc/conf/prod-uid2-config.json | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/aws/conf/prod-euid-config.json b/scripts/aws/conf/prod-euid-config.json index 104f3f4d4..c7784a381 100644 --- a/scripts/aws/conf/prod-euid-config.json +++ b/scripts/aws/conf/prod-euid-config.json @@ -19,7 +19,7 @@ "optout_synthetic_logs_count": 0, "optout_inmem_cache": true, "optout_s3_folder": "optout/", - "identity_token_expires_after_seconds": 86400, + "identity_token_expires_after_seconds": 259200, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/aws/conf/prod-uid2-config.json b/scripts/aws/conf/prod-uid2-config.json index 34eadb0bc..5da450033 100644 --- a/scripts/aws/conf/prod-uid2-config.json +++ b/scripts/aws/conf/prod-uid2-config.json @@ -19,7 +19,7 @@ "optout_synthetic_logs_count": 0, "optout_inmem_cache": true, "optout_s3_folder": "optout-v2/", - "identity_token_expires_after_seconds": 86400, + "identity_token_expires_after_seconds": 259200, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false diff --git a/scripts/azure-cc/conf/prod-uid2-config.json b/scripts/azure-cc/conf/prod-uid2-config.json index a6419b6a5..02e2cde20 100644 --- a/scripts/azure-cc/conf/prod-uid2-config.json +++ b/scripts/azure-cc/conf/prod-uid2-config.json @@ -10,5 +10,6 @@ "optout_metadata_path": "https://optout-prod.uidapi.com/optout/refresh", "core_attest_url": "https://core-prod.uidapi.com/attest", "optout_api_uri": "https://optout-prod.uidapi.com/optout/replicate", - "optout_s3_folder": "optout-v2/" + "optout_s3_folder": "optout-v2/", + "identity_token_expires_after_seconds": 259200 } diff --git a/scripts/gcp-oidc/conf/prod-uid2-config.json b/scripts/gcp-oidc/conf/prod-uid2-config.json index 629c02bf4..6de8b0674 100644 --- a/scripts/gcp-oidc/conf/prod-uid2-config.json +++ b/scripts/gcp-oidc/conf/prod-uid2-config.json @@ -10,5 +10,6 @@ "optout_metadata_path": "https://optout-prod.uidapi.com/optout/refresh", "core_attest_url": "https://core-prod.uidapi.com/attest", "optout_api_uri": "https://optout-prod.uidapi.com/optout/replicate", - "optout_s3_folder": "optout-v2/" + "optout_s3_folder": "optout-v2/", + "identity_token_expires_after_seconds": 259200 } From 2f887c3b6914ea37ce5363fc1a5ea1526d27348c Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 25 Jan 2024 14:32:42 +0800 Subject: [PATCH 0054/1116] Added GCP hint for operator image version --- .github/workflows/run-e2e-tests-on-operator.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 236f8c5c3..d3ad687fc 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -13,7 +13,7 @@ on: - azure - aws operator_image_version: - description: The pipeline will run the E2E test with this operator image version + description: The pipeline will run the E2E test with this operator image version (for GCP, check http://us-docker.pkg.dev/uid2-prod-project/iabtechlab/uid2-operator) type: string default: latest core_image_version: @@ -25,7 +25,7 @@ on: type: string default: latest e2e_image_version: - description: The pipeline will run the E2E test with this e2e image version + description: The pipeline will run the E2E test with this E2E image version type: string default: latest core_branch: From 3a7dea53ed9fd180ea69646296748509ff49ad96 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 25 Jan 2024 14:50:04 +0800 Subject: [PATCH 0055/1116] Updated operator types --- .github/workflows/run-e2e-tests-on-operator.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index d3ad687fc..dd7dd1875 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -4,14 +4,14 @@ on: workflow_dispatch: inputs: operator_type: - description: The operator type [public, gcp, azure, aws] + description: The operator type [Public, GCP, Azure, AWS] required: true type: choice options: - - public - - gcp - - azure - - aws + - Public + - GCP + - Azure + - AWS operator_image_version: description: The pipeline will run the E2E test with this operator image version (for GCP, check http://us-docker.pkg.dev/uid2-prod-project/iabtechlab/uid2-operator) type: string @@ -56,7 +56,7 @@ on: workflow_call: inputs: operator_type: - description: The operator type [public, gcp, azure, aws] + description: The operator type [Public, GCP, Azure, AWS] type: string default: public operator_image_version: From 07b5c78228527020013014ed1d6ca6f182bdef58 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 25 Jan 2024 15:31:11 +0800 Subject: [PATCH 0056/1116] Reverted operator type naming change --- .github/workflows/run-e2e-tests-on-operator.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index dd7dd1875..180f9b5f8 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -1,17 +1,17 @@ name: Run Operator E2E Tests -run-name: ${{ format('Run {0} Operator E2E Tests', inputs.operator_type) }} by @${{ github.actor }} +run-name: ${{ format('Run Operator E2E Tests - {0}', inputs.operator_type) }} by @${{ github.actor }} on: workflow_dispatch: inputs: operator_type: - description: The operator type [Public, GCP, Azure, AWS] + description: The operator type [public, gcp, azure, aws] required: true type: choice options: - - Public - - GCP - - Azure - - AWS + - public + - gcp + - azure + - aws operator_image_version: description: The pipeline will run the E2E test with this operator image version (for GCP, check http://us-docker.pkg.dev/uid2-prod-project/iabtechlab/uid2-operator) type: string @@ -56,7 +56,7 @@ on: workflow_call: inputs: operator_type: - description: The operator type [Public, GCP, Azure, AWS] + description: The operator type [public, gcp, azure, aws] type: string default: public operator_image_version: From db47e7c197b3322e82984c6d80f9ebc627c57f1b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 30 Jan 2024 17:56:34 +0000 Subject: [PATCH 0057/1116] [CI Pipeline] Released Patch version: 5.25.58-4ceeb2e4c5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6955d8f53..4a9fb249d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.56-5cb84da6f1 + 5.25.58-4ceeb2e4c5 UTF-8 From b24b182fe8e8a5f50f28a7c8eef0a4aff05e5034 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 6 Feb 2024 12:08:39 +1100 Subject: [PATCH 0058/1116] Updating dependencies to fix vulnerabilities --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 4a9fb249d..a4ec8810b 100644 --- a/pom.xml +++ b/pom.xml @@ -12,8 +12,8 @@ UTF-8 4.3.8 1.0.22 - 5.7.0 - 5.7.0 + 5.7.2 + 5.7.2 3.0.0 com.uid2.operator.vertx.UIDOperatorVerticle @@ -138,12 +138,12 @@ ch.qos.logback logback-core - 1.3.5 + 1.3.12 ch.qos.logback logback-classic - 1.3.5 + 1.3.12 com.github.loki4j From 85d55e3f58de9a6b2c34428cf6336ee1fa1f06df Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 6 Feb 2024 12:08:39 +1100 Subject: [PATCH 0059/1116] Updating dependencies to fix vulnerabilities --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 4a9fb249d..d756b7fd6 100644 --- a/pom.xml +++ b/pom.xml @@ -12,8 +12,8 @@ UTF-8 4.3.8 1.0.22 - 5.7.0 - 5.7.0 + 5.7.2 + 5.7.2 3.0.0 com.uid2.operator.vertx.UIDOperatorVerticle @@ -22,7 +22,7 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.1.0-649c2e7609 + 6.1.4-6aa70802e2 ${project.version} @@ -138,12 +138,12 @@ ch.qos.logback logback-core - 1.3.5 + 1.3.12 ch.qos.logback logback-classic - 1.3.5 + 1.3.12 com.github.loki4j From e085fc68d58e81ae0c3aa4bcdc2c46cd7d70bf43 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 6 Feb 2024 04:47:27 +0000 Subject: [PATCH 0060/1116] Released Minor version: 5.26.0-454fd430a1 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d756b7fd6..42330a769 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.58-4ceeb2e4c5 + 5.26.0-454fd430a1 UTF-8 diff --git a/version.json b/version.json index 0cbbb5825..0b2f114ba 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.25", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.26", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From f8baac629a2bca4123896ce1fea25a67eb81f6ee Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 8 Feb 2024 15:28:44 +0800 Subject: [PATCH 0061/1116] Updated AWS entrypoint --- scripts/aws/entrypoint.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 0385487f1..bb3a0c126 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -15,26 +15,37 @@ echo "Starting vsock proxy..." echo "Loading env vars via proxy..." if [ "${IDENTITY_SCOPE}" = "UID2" ]; then - UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") + USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) + UID2_CONFIG_SECRET_KEY=$([[ "$(echo USER_DATA | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") + CORE_BASE_URL=$([[ "$(echo USER_DATA | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") + OPTOUT_BASE_URL=$([[ "$(echo USER_DATA | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") + ENFORCE_HTTPS=$([[ "$(echo USER_DATA | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then - UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") + USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) + UID2_CONFIG_SECRET_KEY=$([[ "$(echo USER_DATA | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") + CORE_BASE_URL=$([[ "$(echo USER_DATA | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") + OPTOUT_BASE_URL=$([[ "$(echo USER_DATA | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") + ENFORCE_HTTPS=$([[ "$(echo USER_DATA | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") else echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" exit 1 fi echo "UID2_CONFIG_SECRET_KEY=${UID2_CONFIG_SECRET_KEY}" +echo "CORE_BASE_URL=${CORE_BASE_URL}" +echo "OPTOUT_BASE_URL=${OPTOUT_BASE_URL}" +echo "ENFORCE_HTTPS=${ENFORCE_HTTPS}" export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r '.region') echo "AWS_REGION_NAME=${AWS_REGION_NAME}" echo "127.0.0.1 secretsmanager.${AWS_REGION_NAME}.amazonaws.com" >> /etc/hosts IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/iam/security-credentials/) -echo "IAM_ROLE=$IAM_ROLE" +echo "IAM_ROLE=${IAM_ROLE}" -CREDS_ENDPOINT="http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE" -export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 $CREDS_ENDPOINT | jq -r '.AccessKeyId') -export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 $CREDS_ENDPOINT | jq -r '.SecretAccessKey') -export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 $CREDS_ENDPOINT | jq -r '.Token') +CREDS_ENDPOINT="http://169.254.169.254/latest/meta-data/iam/security-credentials/${IAM_ROLE}" +export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r '.AccessKeyId') +export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r '.SecretAccessKey') +export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r '.Token') # -- load configs via proxy echo "Loading config overrides..." @@ -42,6 +53,7 @@ export OVERRIDES_CONFIG="/app/conf/config-overrides.json" python3 /app/load_config.py > ${OVERRIDES_CONFIG} export DEPLOYMENT_ENVIRONMENT=$(jq -r '.environment' < ${OVERRIDES_CONFIG}) +echo "DEPLOYMENT_ENVIRONMENT=${DEPLOYMENT_ENVIRONMENT}" if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then echo "DEPLOYMENT_ENVIRONMENT cannot be empty" exit 1 From ec41eb45093a2af83b5cda41a070669861bce10e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 8 Feb 2024 16:48:49 +0800 Subject: [PATCH 0062/1116] Added debug line --- scripts/aws/entrypoint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index bb3a0c126..f115347a8 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -16,6 +16,7 @@ echo "Loading env vars via proxy..." if [ "${IDENTITY_SCOPE}" = "UID2" ]; then USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) + echo ${USER_DATA} UID2_CONFIG_SECRET_KEY=$([[ "$(echo USER_DATA | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") CORE_BASE_URL=$([[ "$(echo USER_DATA | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") OPTOUT_BASE_URL=$([[ "$(echo USER_DATA | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") From c49bbfdaf3e3775e8797db827aa23933c39a7ebb Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 8 Feb 2024 17:13:20 +0800 Subject: [PATCH 0063/1116] Updated env var fetching --- scripts/aws/entrypoint.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index f115347a8..af891e0a7 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -16,17 +16,16 @@ echo "Loading env vars via proxy..." if [ "${IDENTITY_SCOPE}" = "UID2" ]; then USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) - echo ${USER_DATA} - UID2_CONFIG_SECRET_KEY=$([[ "$(echo USER_DATA | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") - CORE_BASE_URL=$([[ "$(echo USER_DATA | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") - OPTOUT_BASE_URL=$([[ "$(echo USER_DATA | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") - ENFORCE_HTTPS=$([[ "$(echo USER_DATA | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") + UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") + CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") + OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") + ENFORCE_HTTPS=$([[ "$(echo "${USER_DATA}" | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "false") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) - UID2_CONFIG_SECRET_KEY=$([[ "$(echo USER_DATA | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") - CORE_BASE_URL=$([[ "$(echo USER_DATA | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") - OPTOUT_BASE_URL=$([[ "$(echo USER_DATA | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") - ENFORCE_HTTPS=$([[ "$(echo USER_DATA | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\" ]] && echo "${BASH_REMATCH[1]}" || echo "") + UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") + CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") + OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") + ENFORCE_HTTPS=$([[ "$(echo "${USER_DATA}" | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "false") else echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" exit 1 From c8f7e951009b23317690b25de3d71257c5b5fcab Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 9 Feb 2024 12:26:50 +0800 Subject: [PATCH 0064/1116] Added missing jq_inplace_update_json function --- scripts/aws/entrypoint.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index af891e0a7..88b29a8c6 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -3,6 +3,16 @@ set -o pipefail ulimit -n 65536 +# for number/boolean +# https://jqlang.github.io/jq/manual/ +# --argjson foo 123 will bind $foo to 123. +function jq_inplace_update_json() { + local file=$1 + local field=$2 + local value=$3 + jq --argjson v "$value" ".$field = \$v" "$file" > $TMP_FINAL_CONFIG && mv $TMP_FINAL_CONFIG "$file" +} + # -- setup loopback device echo "Setting up loopback device..." ifconfig lo 127.0.0.1 From 9203daa0269ca572fa13e35fd8b48c082e176f79 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 9 Feb 2024 12:46:30 +0800 Subject: [PATCH 0065/1116] Fixed script formatting --- scripts/aws/entrypoint.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 88b29a8c6..a41ec46c7 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -10,7 +10,7 @@ function jq_inplace_update_json() { local file=$1 local field=$2 local value=$3 - jq --argjson v "$value" ".$field = \$v" "$file" > $TMP_FINAL_CONFIG && mv $TMP_FINAL_CONFIG "$file" + jq --argjson v "${value}" ".${field} = \$v" "${file}" > ${TMP_FINAL_CONFIG} && mv ${TMP_FINAL_CONFIG} "${file}" } # -- setup loopback device @@ -45,7 +45,7 @@ echo "CORE_BASE_URL=${CORE_BASE_URL}" echo "OPTOUT_BASE_URL=${OPTOUT_BASE_URL}" echo "ENFORCE_HTTPS=${ENFORCE_HTTPS}" -export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r '.region') +export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r ".region") echo "AWS_REGION_NAME=${AWS_REGION_NAME}" echo "127.0.0.1 secretsmanager.${AWS_REGION_NAME}.amazonaws.com" >> /etc/hosts @@ -53,31 +53,31 @@ IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/met echo "IAM_ROLE=${IAM_ROLE}" CREDS_ENDPOINT="http://169.254.169.254/latest/meta-data/iam/security-credentials/${IAM_ROLE}" -export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r '.AccessKeyId') -export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r '.SecretAccessKey') -export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r '.Token') +export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r ".AccessKeyId") +export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r ".SecretAccessKey") +export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r ".Token") # -- load configs via proxy echo "Loading config overrides..." export OVERRIDES_CONFIG="/app/conf/config-overrides.json" python3 /app/load_config.py > ${OVERRIDES_CONFIG} -export DEPLOYMENT_ENVIRONMENT=$(jq -r '.environment' < ${OVERRIDES_CONFIG}) +export DEPLOYMENT_ENVIRONMENT=$(jq -r ".environment" < ${OVERRIDES_CONFIG}) echo "DEPLOYMENT_ENVIRONMENT=${DEPLOYMENT_ENVIRONMENT}" if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then echo "DEPLOYMENT_ENVIRONMENT cannot be empty" exit 1 fi -if [ "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ] && [ "${DEPLOYMENT_ENVIRONMENT}" != 'integ' ]; then +if [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "integ" ]; then echo "Unrecognized DEPLOYMENT_ENVIRONMENT ${DEPLOYMENT_ENVIRONMENT}" exit 1 fi echo "Loading config final..." export FINAL_CONFIG="/app/conf/config-final.json" -if [ "${IDENTITY_SCOPE}" = 'UID2' ]; then +if [ "${IDENTITY_SCOPE}" = "UID2" ]; then python3 /app/make_config.py /app/conf/prod-uid2-config.json /app/conf/integ-uid2-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} -elif [ "${IDENTITY_SCOPE}" = 'EUID' ]; then +elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then python3 /app/make_config.py /app/conf/prod-euid-config.json /app/conf/integ-euid-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} else echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" From 5b15a1820bfa7458320e2588c489ca77ade07dac Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 9 Feb 2024 13:44:36 +0800 Subject: [PATCH 0066/1116] Fixed variable reference in function --- scripts/aws/entrypoint.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index a41ec46c7..f9b8377c1 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -3,16 +3,6 @@ set -o pipefail ulimit -n 65536 -# for number/boolean -# https://jqlang.github.io/jq/manual/ -# --argjson foo 123 will bind $foo to 123. -function jq_inplace_update_json() { - local file=$1 - local field=$2 - local value=$3 - jq --argjson v "${value}" ".${field} = \$v" "${file}" > ${TMP_FINAL_CONFIG} && mv ${TMP_FINAL_CONFIG} "${file}" -} - # -- setup loopback device echo "Setting up loopback device..." ifconfig lo 127.0.0.1 @@ -88,6 +78,17 @@ get_config_value() { jq -r ".\"$1\"" ${FINAL_CONFIG} } +# for number/boolean +# https://jqlang.github.io/jq/manual/ +# --argjson foo 123 will bind $foo to 123. +TMP_FINAL_CONFIG="/tmp/final-config.tmp" +function jq_inplace_update_json() { + local file=$1 + local field=$2 + local value=$3 + jq --argjson v "${value}" ".${field} = \$v" "${file}" > ${TMP_FINAL_CONFIG} && mv ${TMP_FINAL_CONFIG} "${file}" +} + # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then From 74dce9b5938746975cff2238f231764b7b2889d4 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 9 Feb 2024 14:55:21 +0800 Subject: [PATCH 0067/1116] Added debug --- scripts/aws/Dockerfile | 24 ++++++++++++------------ scripts/aws/entrypoint.sh | 26 ++++++++++++++------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 253826995..a8fb76d99 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -11,7 +11,7 @@ ENV JAR_NAME=${JAR_NAME} ENV JAR_VERSION=${JAR_VERSION} ENV IMAGE_VERSION=${IMAGE_VERSION} ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} -ENV ENCLAVE_ENVIRONMENT=aws-nitro +ENV ENCLAVE_ENVIRONMENT="aws-nitro" ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" RUN apt update -y \ @@ -20,18 +20,18 @@ RUN apt update -y \ RUN pip3 install boto3==1.16.9 COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar -COPY ./static /app/static -COPY ./vsockpx /app/ -COPY ./libjnsm.so /app/lib/ -COPY ./load_config.py /app/ -COPY ./make_config.py /app/ -COPY ./entrypoint.sh /app/ -COPY ./proxies.nitro.yaml /app/ +COPY ./static /app/static +COPY ./vsockpx /app/ +COPY ./load_config.py /app/ +COPY ./make_config.py /app/ +COPY ./entrypoint.sh /app/ +COPY ./proxies.nitro.yaml /app/ +COPY ./libjnsm.so /app/lib/ COPY ./conf/default-config.json /app/conf/ -COPY ./conf/prod-uid2-config.json /app/conf/prod-uid2-config.json -COPY ./conf/integ-uid2-config.json /app/conf/integ-uid2-config.json -COPY ./conf/prod-euid-config.json /app/conf/prod-euid-config.json -COPY ./conf/integ-euid-config.json /app/conf/integ-euid-config.json +COPY ./conf/prod-uid2-config.json /app/conf/ +COPY ./conf/integ-uid2-config.json /app/conf/ +COPY ./conf/prod-euid-config.json /app/conf/ +COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index f9b8377c1..0a51cb45f 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash -euf +#!/bin/bash -eufx set -o pipefail ulimit -n 65536 @@ -43,16 +43,16 @@ IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/met echo "IAM_ROLE=${IAM_ROLE}" CREDS_ENDPOINT="http://169.254.169.254/latest/meta-data/iam/security-credentials/${IAM_ROLE}" -export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r ".AccessKeyId") -export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r ".SecretAccessKey") -export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 ${CREDS_ENDPOINT} | jq -r ".Token") +export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 "${CREDS_ENDPOINT}" | jq -r ".AccessKeyId") +export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 "${CREDS_ENDPOINT}" | jq -r ".SecretAccessKey") +export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 "${CREDS_ENDPOINT}" | jq -r ".Token") # -- load configs via proxy echo "Loading config overrides..." export OVERRIDES_CONFIG="/app/conf/config-overrides.json" -python3 /app/load_config.py > ${OVERRIDES_CONFIG} +python3 /app/load_config.py > "${OVERRIDES_CONFIG}" -export DEPLOYMENT_ENVIRONMENT=$(jq -r ".environment" < ${OVERRIDES_CONFIG}) +export DEPLOYMENT_ENVIRONMENT=$(jq -r ".environment" < "${OVERRIDES_CONFIG}") echo "DEPLOYMENT_ENVIRONMENT=${DEPLOYMENT_ENVIRONMENT}" if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then echo "DEPLOYMENT_ENVIRONMENT cannot be empty" @@ -86,23 +86,25 @@ function jq_inplace_update_json() { local file=$1 local field=$2 local value=$3 - jq --argjson v "${value}" ".${field} = \$v" "${file}" > ${TMP_FINAL_CONFIG} && mv ${TMP_FINAL_CONFIG} "${file}" + jq --argjson v "${value}" ".${field} = \$v" "${file}" > "${TMP_FINAL_CONFIG}" && mv "${TMP_FINAL_CONFIG}" "${file}" } # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..." - sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} - sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} + sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" fi # -- replace `enforce_https` value to ENFORCE_HTTPS if provided if [ "${ENFORCE_HTTPS}" == false ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then echo "Replacing enforce_https by ${ENFORCE_HTTPS}..." - jq_inplace_update_json ${FINAL_CONFIG} enforce_https false + jq_inplace_update_json "${FINAL_CONFIG}" enforce_https false fi +cat "${FINAL_CONFIG}" + # -- setup loki echo "Setting up Loki..." [[ "$(get_config_value 'loki_enabled')" == "true" ]] \ @@ -121,7 +123,7 @@ java \ -XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \ -Djava.security.egd=file:/dev/./urandom \ -Djava.library.path=/app/lib \ - -Dvertx-config-path=/app/conf/config-final.json \ - "$SETUP_LOKI_LINE" \ + -Dvertx-config-path="${FINAL_CONFIG}" \ + "${SETUP_LOKI_LINE}" \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar From f8a43b5b1cc3e1d6d7923d77129f2ba5089decf6 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 9 Feb 2024 15:55:08 +0800 Subject: [PATCH 0068/1116] Updated URL paths --- scripts/aws/entrypoint.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 0a51cb45f..68d20af7b 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -94,7 +94,9 @@ function jq_inplace_update_json() { if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..." sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://core-prod.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout-prod.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" fi # -- replace `enforce_https` value to ENFORCE_HTTPS if provided @@ -124,6 +126,6 @@ java \ -Djava.security.egd=file:/dev/./urandom \ -Djava.library.path=/app/lib \ -Dvertx-config-path="${FINAL_CONFIG}" \ - "${SETUP_LOKI_LINE}" \ + $SETUP_LOKI_LINE \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar From 704205858bac44c2bb4e45a0c9acc60e9fcd914f Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 9 Feb 2024 19:45:13 +0800 Subject: [PATCH 0069/1116] Updated formatting --- scripts/aws/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 68d20af7b..c4095c395 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -126,6 +126,6 @@ java \ -Djava.security.egd=file:/dev/./urandom \ -Djava.library.path=/app/lib \ -Dvertx-config-path="${FINAL_CONFIG}" \ - $SETUP_LOKI_LINE \ + ${SETUP_LOKI_LINE} \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar From b8ba9b4b3e287fac083e7cb9e781c63bf8a05010 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 12 Feb 2024 11:51:26 +1100 Subject: [PATCH 0070/1116] Removed the ability to set the urls from the environment This will break the e2e testing, but is required to keep the operators secure --- scripts/azure-cc/entrypoint.sh | 20 ++++++++++---------- scripts/gcp-oidc/entrypoint.sh | 18 +++++++++--------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index fcbaa8d5e..286eedd84 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -53,18 +53,18 @@ fi # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently -if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then - echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" - sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} - - sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} -fi +#if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then +# echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" +# sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} +# +# sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} +#fi # -- replace `enforce_https` value to ENFORCE_HTTPS if provided -if [ "${ENFORCE_HTTPS}" == false ]; then - echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" - jq_inplace_update_json $FINAL_CONFIG enforce_https false -fi +#if [ "${ENFORCE_HTTPS}" == false ]; then +# echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" +# jq_inplace_update_json $FINAL_CONFIG enforce_https false +#fi cat $FINAL_CONFIG diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index a51e1862b..08effd77f 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -47,18 +47,18 @@ fi # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently -if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then - echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" - sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} +#if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then +# echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" +# sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} - sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} -fi +# sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} +#fi # -- replace `enforce_https` value to ENFORCE_HTTPS if provided -if [ "${ENFORCE_HTTPS}" == false ]; then - echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" - jq_inplace_update_json $FINAL_CONFIG enforce_https false -fi +#if [ "${ENFORCE_HTTPS}" == false ]; then +# echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" +# jq_inplace_update_json $FINAL_CONFIG enforce_https false +#fi cat $FINAL_CONFIG From ecb173f79ee17762261888cc74f20acc6d36515f Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 12 Feb 2024 14:10:02 +1100 Subject: [PATCH 0071/1116] Add `skip_e2e_test` as inputs (#348) * Add `skip_e2e_test` as inputs * Make skip_e2e_test default to false --- .github/workflows/publish-all-operators.yaml | 6 ++++++ .github/workflows/publish-azure-cc-enclave-docker.yaml | 9 +++++++++ .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index f452d431b..b3ea593d4 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -10,6 +10,10 @@ on: - Major - Minor - Patch + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false jobs: start: @@ -81,6 +85,7 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} + skip_e2e_test: ${{ inputs.skip_e2e_test }} secrets: inherit buildAzure: @@ -90,6 +95,7 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} + skip_e2e_test: ${{ inputs.skip_e2e_test }} secrets: inherit collectAllArtifacts: diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 05d0f61e9..0b357bc3c 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -15,6 +15,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false workflow_call: inputs: release_type: @@ -25,6 +29,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false outputs: image_tag: @@ -245,6 +253,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml + if: ${{ inputs.skip_e2e_test != 'true'}} needs: buildImage with: operator_type: azure diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 5c9da76d2..efc932546 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -15,6 +15,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false workflow_call: inputs: release_type: @@ -25,6 +29,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false outputs: image_tag: @@ -282,6 +290,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml + if: ${{ inputs.skip_e2e_test != 'true'}} needs: buildImage with: operator_type: gcp From d439fc291fd6663fdcd72e8e544fe0b55fd7666b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 03:12:48 +0000 Subject: [PATCH 0072/1116] Released Patch version: 5.26.4-ecb173f79e --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42330a769..c1406c0dc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.0-454fd430a1 + 5.26.4-ecb173f79e UTF-8 From 4704c5f625ea7915f892886d1340da1134bb4867 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 03:13:54 +0000 Subject: [PATCH 0073/1116] Released Patch version: 5.26.5-d439fc291f --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c1406c0dc..22e321d75 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.4-ecb173f79e + 5.26.5-d439fc291f UTF-8 From 0856fcea17972b3d7886ed05ca0a5956c87d8666 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 12 Feb 2024 14:47:24 +1100 Subject: [PATCH 0074/1116] Use `if: ${{ inputs.skip_e2e_test || true }}` (#349) --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 2 +- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 0b357bc3c..59ad4edb1 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -253,7 +253,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test != 'true'}} + if: ${{ inputs.skip_e2e_test || true }} needs: buildImage with: operator_type: azure diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index efc932546..8d2940c05 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -290,7 +290,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test != 'true'}} + if: ${{ inputs.skip_e2e_test || true }} needs: buildImage with: operator_type: gcp From 2c836f96c49de33d1a8f970014b5ced4cfefe801 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 03:50:42 +0000 Subject: [PATCH 0075/1116] Released Patch version: 5.26.7-0856fcea17 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 22e321d75..7e459dedc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.5-d439fc291f + 5.26.7-0856fcea17 UTF-8 From b926641f9638cbef0f0d95adaeaf2ddeb15bde7e Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 12 Feb 2024 14:56:47 +1100 Subject: [PATCH 0076/1116] Fix skip_e2e_test logic (#350) --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 2 +- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 59ad4edb1..f05a33713 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -253,7 +253,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test || true }} + if: ${{ inputs.skip_e2e_test }} needs: buildImage with: operator_type: azure diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 8d2940c05..bd268136c 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -290,7 +290,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test || true }} + if: ${{ inputs.skip_e2e_test }} needs: buildImage with: operator_type: gcp From cecfa1d2c425f1c7c7d35cac06bab215cf7f83ab Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 03:59:12 +0000 Subject: [PATCH 0077/1116] Released Patch version: 5.26.9-b926641f96 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7e459dedc..65debd103 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.7-0856fcea17 + 5.26.9-b926641f96 UTF-8 From d0105216563aeb1cba87ae0118c7dd9d21787ca3 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 12 Feb 2024 15:09:17 +1100 Subject: [PATCH 0078/1116] Fix skip_e2e_test logic (#351) --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 2 +- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index f05a33713..835b2690f 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -253,7 +253,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test }} + if: ${{ inputs.skip_e2e_test || false }} needs: buildImage with: operator_type: azure diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index bd268136c..3da857490 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -290,7 +290,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test }} + if: ${{ inputs.skip_e2e_test || false }} needs: buildImage with: operator_type: gcp From 89342e9fa0d732d6eeb67d8b966d06de82366a10 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 04:12:04 +0000 Subject: [PATCH 0079/1116] Released Patch version: 5.26.11-d010521656 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 65debd103..f5224e970 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.9-b926641f96 + 5.26.11-d010521656 UTF-8 From cf60ffaa41180625cdbaa4ec5c4c3b267656cfec Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 04:14:59 +0000 Subject: [PATCH 0080/1116] Released Patch version: 5.26.12-89342e9fa0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f5224e970..3d0b4b5f7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.11-d010521656 + 5.26.12-89342e9fa0 UTF-8 From 79b05a7039b879f06b505903959af19a7d5e6059 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 04:20:32 +0000 Subject: [PATCH 0081/1116] Released Patch version: 5.26.13-cf60ffaa41 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3d0b4b5f7..130c25b09 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.12-89342e9fa0 + 5.26.13-cf60ffaa41 UTF-8 From 496d3c36460fd2c4f72e64ca99ce14f74c916a5b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 12 Feb 2024 15:39:19 +1100 Subject: [PATCH 0082/1116] Removed override policy from docker file --- scripts/gcp-oidc/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 059558fd4..15d775838 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d -LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL,ENFORCE_HTTPS" +LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT" # Install Packages RUN apk update && apk add jq From 3914f499130022b5ac6bc23c01aef2daeefd01ad Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 12 Feb 2024 16:00:01 +1100 Subject: [PATCH 0083/1116] Fix skip_e2e_test logic (#352) * Trigger workflow on pull_request * Use `if: ${{ inputs.skip_e2e_test == 'false' }}` to skip e2e jobs * Use `if: ${{ inputs.skip_e2e_test == 'false' }}` to check e2e tests --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 2 +- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 835b2690f..01a317a63 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -253,7 +253,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test || false }} + if: ${{ inputs.skip_e2e_test == 'false' }} needs: buildImage with: operator_type: azure diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 3da857490..27591bb6d 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -290,7 +290,7 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test || false }} + if: ${{ inputs.skip_e2e_test == 'false' }} needs: buildImage with: operator_type: gcp From e43e05fe63d6cfd5176218222a073139c2681fc9 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 05:02:32 +0000 Subject: [PATCH 0084/1116] Released Patch version: 5.26.15-3914f49913 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 130c25b09..fb5bf24bc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.13-cf60ffaa41 + 5.26.15-3914f49913 UTF-8 From 507dd1c530a9a19d3d5f1b96855f8f39e56805d9 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 12 Feb 2024 16:21:42 +1100 Subject: [PATCH 0085/1116] Updated shared to prevent override of enforce https --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb5bf24bc..df89d46d1 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 1.1.0 1.5.0-115595d597 1.4.2-dd1920710d - 6.1.4-6aa70802e2 + 6.1.8-6e6866128b ${project.version} From 6dac44d7afa790d7a74512cb16979339278aa280 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 12 Feb 2024 05:42:58 +0000 Subject: [PATCH 0086/1116] Released Patch version: 5.26.19-56899dc0d7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index df89d46d1..36f952e6c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.15-3914f49913 + 5.26.19-56899dc0d7 UTF-8 From d4082509df644545a6b1bbf13fdea531c256d7f3 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 14 Feb 2024 14:25:14 +0800 Subject: [PATCH 0087/1116] Syw UID2-2635 change cstg to send out optout response if optout_check=1 is specified (#343) * Always return optout status/response in CSTG call if optout_check=1 is set in the encrypted payload of a CSTG request or if it's EUID. * Created a new PrivacyBits#BIT_CSTG_OPTOUT_RESPONSE field to indicate whether the original CSTG token generation has provided the optout check field so that it will retain the same behavior for token refresh later on --- .../uid2/operator/service/ResponseUtil.java | 7 +- .../operator/service/UIDOperatorService.java | 16 ++- .../com/uid2/operator/util/PrivacyBits.java | 7 +- .../operator/vertx/UIDOperatorVerticle.java | 51 +++++--- .../operator/ExtendedUIDOperatorVerticle.java | 1 + .../operator/UIDOperatorVerticleTest.java | 123 ++++++++++++++---- 6 files changed, 158 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/ResponseUtil.java b/src/main/java/com/uid2/operator/service/ResponseUtil.java index f2abb722f..a515d1f34 100644 --- a/src/main/java/com/uid2/operator/service/ResponseUtil.java +++ b/src/main/java/com/uid2/operator/service/ResponseUtil.java @@ -36,12 +36,17 @@ public static void Success(RoutingContext rc, Object body) { .end(json.encode()); } - public static void SuccessNoBodyV2(String status, RoutingContext rc) { + public static JsonObject SuccessNoBodyV2(String status) { final JsonObject json = new JsonObject(new HashMap<>() { { put("status", status); } }); + return json; + } + + public static void SuccessNoBodyV2(String status, RoutingContext rc) { + final JsonObject json = SuccessNoBodyV2(status); rc.data().put("response", json); } diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index ca1ebe695..581e2970e 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -51,7 +51,8 @@ public class UIDOperatorService implements IUIDOperatorService { private final TokenVersion refreshTokenVersion; private final boolean identityV3Enabled; - public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProvider saltProvider, ITokenEncoder encoder, Clock clock, IdentityScope identityScope) { + public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProvider saltProvider, ITokenEncoder encoder, Clock clock, + IdentityScope identityScope) { this.saltProvider = saltProvider; this.encoder = encoder; this.optOutStore = optOutStore; @@ -128,6 +129,8 @@ public RefreshResponse refreshIdentity(RefreshToken token) { final PrivacyBits privacyBits = PrivacyBits.fromInt(token.userIdentity.privacyBits); final boolean isCstg = privacyBits.isClientSideTokenGenerated(); + final boolean hasCstgOptOutCheckFlag = privacyBits.isClientSideTokenGenerateOptoutResponseOn(); + final boolean shouldCstgOptedOutUserReturnOptOutToken = !shouldCstgOptedOutUserReturnOptOutResponse(identityScope, hasCstgOptOutCheckFlag); try { final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(token.userIdentity, true); @@ -139,7 +142,8 @@ public RefreshResponse refreshIdentity(RefreshToken token) { IdentityTokens identityTokens = this.generateIdentity(token.publisherIdentity, token.userIdentity); return RefreshResponse.createRefreshedResponse(identityTokens, durationSinceLastRefresh, isCstg); - } else if (isCstg) { + } else if (isCstg && shouldCstgOptedOutUserReturnOptOutToken) { + // The user has opted out after the userIdentity was established. privacyBits.setClientSideTokenGenerateOptout(); @@ -342,4 +346,12 @@ public TokenVersion getAdvertisingTokenVersionForTests() { assert this.advertisingTokenV4Percentage == 0 || this.advertisingTokenV4Percentage == 100; //we want tests to be deterministic return this.advertisingTokenV4Percentage == 100 ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } + + public static boolean shouldCstgOptedOutUserReturnOptOutResponse(IdentityScope identityScope, + boolean cstgRequestHasOptoutCheckFlag) { + if (identityScope == IdentityScope.EUID) { + return true; + } + return cstgRequestHasOptoutCheckFlag; + } } diff --git a/src/main/java/com/uid2/operator/util/PrivacyBits.java b/src/main/java/com/uid2/operator/util/PrivacyBits.java index d2ff17a2e..3cab2937b 100644 --- a/src/main/java/com/uid2/operator/util/PrivacyBits.java +++ b/src/main/java/com/uid2/operator/util/PrivacyBits.java @@ -6,7 +6,7 @@ public class PrivacyBits { private static final int BIT_LEGACY = 0; private static final int BIT_CSTG = 1; private static final int BIT_CSTG_OPTOUT = 2; - + private static final int BIT_CSTG_OPTOUT_RESPONSE = 3; private int bits = 0; @@ -33,6 +33,11 @@ public boolean isClientSideTokenOptedOut() { return isBitSet(BIT_CSTG_OPTOUT); } + public void setClientSideTokenGenerateOptoutResponse() { setBit(BIT_CSTG_OPTOUT_RESPONSE); } + public boolean isClientSideTokenGenerateOptoutResponseOn() { + return isBitSet(BIT_CSTG_OPTOUT_RESPONSE); + } + public void setLegacyBit() { setBit(BIT_LEGACY);//unknown why this bit is set in https://github.com/IABTechLab/uid2-operator/blob/dbab58346e367c9d4122ad541ff9632dc37bd410/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java#L534 } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index fb788af9f..b5c2a4760 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1,7 +1,6 @@ package com.uid2.operator.vertx; import com.uid2.operator.Const; -import com.uid2.operator.IdentityConst; import com.uid2.operator.model.*; import com.uid2.operator.model.IdentityScope; import com.uid2.operator.monitoring.IStatsCollectorQueue; @@ -375,6 +374,8 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA final String emailHash = requestPayload.getString("email_hash"); final String phoneHash = requestPayload.getString("phone_hash"); + final int optoutCheck = requestPayload.getInteger("optout_check", 0); + final boolean cstgRequestHasOptoutCheckFlag = optoutCheck == OptoutCheckPolicy.RespectOptOut.ordinal(); final InputUtil.InputVal input; @@ -403,34 +404,54 @@ else if(emailHash != null) { privacyBits.setLegacyBit(); privacyBits.setClientSideTokenGenerate(); + if(cstgRequestHasOptoutCheckFlag) { + privacyBits.setClientSideTokenGenerateOptoutResponse(); + } + IdentityTokens identityTokens = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), input.toUserIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), OptoutCheckPolicy.RespectOptOut)); + JsonObject response; + TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; if (identityTokens.isEmptyToken()) { - //user opted out we will generate a token with the opted out user identity - privacyBits.setClientSideTokenGenerateOptout(); - UserIdentity cstgOptOutIdentity; - if(input.getIdentityType() == IdentityType.Email) { - cstgOptOutIdentity = InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail).toUserIdentity(identityScope, privacyBits.getAsInt(), Instant.now()); + if (UIDOperatorService.shouldCstgOptedOutUserReturnOptOutResponse(identityScope, cstgRequestHasOptoutCheckFlag)) { + response = ResponseUtil.SuccessNoBodyV2("optout"); + responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } else { - cstgOptOutIdentity = InputUtil.InputVal.validPhone(OptOutTokenIdentityForPhone, OptOutTokenIdentityForPhone).toUserIdentity(identityScope, privacyBits.getAsInt(), Instant.now()); + privacyBits.setClientSideTokenGenerateOptout(); + //user opted out we will generate an optout token with the opted out user identity + identityTokens = generateOptedOutIdentityTokens(privacyBits, input, clientSideKeypair); + response = ResponseUtil.SuccessV2(toJsonV1(identityTokens)); } - identityTokens = this.idService.generateIdentity( - new IdentityRequest( - new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), - cstgOptOutIdentity, OptoutCheckPolicy.DoNotRespect)); } - JsonObject response = ResponseUtil.SuccessV2(toJsonV1(identityTokens)); - V2RequestUtil.handleRefreshTokenInResponseBody(response.getJsonObject("body"), keyManager, this.identityScope); - + else { //user not opted out and already generated valid identity token + response = ResponseUtil.SuccessV2(toJsonV1(identityTokens)); + } + //if returning an optout token or a successful identity token created originally + if (responseStatus == TokenResponseStatsCollector.ResponseStatus.Success) { + V2RequestUtil.handleRefreshTokenInResponseBody(response.getJsonObject("body"), keyManager, this.identityScope); + } final byte[] encryptedResponse = AesGcm.encrypt(response.toBuffer().getBytes(), sharedSecret); rc.response().setStatusCode(200).end(Buffer.buffer(Unpooled.wrappedBuffer(Base64.getEncoder().encode(encryptedResponse)))); - recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, identityTokens.getAdvertisingTokenVersion()); + recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityTokens.getAdvertisingTokenVersion()); + } + + private IdentityTokens generateOptedOutIdentityTokens(PrivacyBits privacyBits, InputUtil.InputVal input, ClientSideKeypair clientSideKeypair) { + UserIdentity cstgOptOutIdentity; + if (input.getIdentityType() == IdentityType.Email) { + cstgOptOutIdentity = InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail).toUserIdentity(identityScope, privacyBits.getAsInt(), Instant.now()); + } else { + cstgOptOutIdentity = InputUtil.InputVal.validPhone(OptOutTokenIdentityForPhone, OptOutTokenIdentityForPhone).toUserIdentity(identityScope, privacyBits.getAsInt(), Instant.now()); + } + return this.idService.generateIdentity( + new IdentityRequest( + new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), + cstgOptOutIdentity, OptoutCheckPolicy.DoNotRespect)); } private byte[] decrypt(byte[] encryptedBytes, int offset, byte[] secretBytes, byte[] aad) throws InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index 7b1eaa951..38f5eeb7c 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -4,6 +4,7 @@ import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.service.IUIDOperatorService; import com.uid2.operator.service.SecureLinkValidatorService; +import com.uid2.operator.service.UIDOperatorService; import com.uid2.operator.store.IOptOutStore; import com.uid2.operator.vertx.UIDOperatorVerticle; import com.uid2.shared.store.*; diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 48d6e9b92..b73531183 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -2695,10 +2695,15 @@ void cstgNoIdentityHashProvided(Vertx vertx, VertxTestContext testContext) throw } @ParameterizedTest - @ValueSource(strings = {"https://blahblah.com", "http://local1host:8080"}) - void cstgDomainNameCheckFails(String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + @CsvSource({ + "true,https://blahblah.com", + "false,https://blahblah.com", + "true,http://local1host:8080", //intentionally spelling localhost wrong here! + "false,http://local1host:8080", + }) + void cstgDomainNameCheckFails(boolean setOptoutCheckFlagInRequest, String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend(); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -2719,10 +2724,17 @@ void cstgDomainNameCheckFails(String httpOrigin, Vertx vertx, VertxTestContext t } @ParameterizedTest - @ValueSource(strings = {"https://cstg.co.uk", "https://cstg2.com", "http://localhost:8080"}) - void cstgDomainNameCheckPasses(String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + @CsvSource({ + "true,https://cstg.co.uk", + "false,https://cstg.co.uk", + "true,https://cstg2.com", + "false,https://cstg2.com", + "true,http://localhost:8080", + "false,http://localhost:8080", + }) + void cstgDomainNameCheckPasses(boolean setOptoutCheckFlagInRequest, String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk", "cstg2.com", "localhost"); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -3184,7 +3196,7 @@ private Tuple.Tuple2 createClientSideTokenGenerateRequest return new Tuple.Tuple2<>(requestJson, secretKey); } - private Tuple.Tuple2 createClientSideTokenGenerateRequest(IdentityType identityType, String rawId, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException { + private Tuple.Tuple2 createClientSideTokenGenerateRequest(IdentityType identityType, String rawId, long timestamp, boolean setOptoutCheckFlagInRequest) throws NoSuchAlgorithmException, InvalidKeyException { JsonObject identity = new JsonObject(); @@ -3197,6 +3209,11 @@ else if(identityType == IdentityType.Phone) { else { //can't be other types assertFalse(true); } + + if(setOptoutCheckFlagInRequest) { + identity.put("optout_check", 1); + } + return createClientSideTokenGenerateRequestWithPayload(identity, timestamp); } @@ -3207,11 +3224,16 @@ private Tuple.Tuple2 createClientSideTokenGenerateRequest @ParameterizedTest - @CsvSource({"test@example.com,Email", "+61400000000,Phone"}) - void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + @CsvSource({ + "true,test@example.com,Email", + "true,+61400000000,Phone", + "false,test@example.com,Email", + "false,+61400000000,Phone", + }) + void cstgUserOptsOutAfterTokenGenerate(boolean setOptoutCheckFlagInRequest, String id, IdentityType identityType, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk"); - final Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli()); + final Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); // When we generate the token the user hasn't opted out. when(optOutStore.getLatestEntry(any(UserIdentity.class))) @@ -3237,13 +3259,23 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver final AdvertisingToken advertisingToken = validateAndGetToken(encoder, genBody, identityType); final RefreshToken refreshToken = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); - assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id, setOptoutCheckFlagInRequest); // When we refresh the token the user has opted out. when(optOutStore.getLatestEntry(any(UserIdentity.class))) .thenReturn(advertisingToken.userIdentity.establishedAt.plusSeconds(1)); sendTokenRefresh("v2", vertx, testContext, genBody.getString("refresh_token"), genBody.getString("refresh_response_key"), 200, refreshRespJson -> { + + if (setOptoutCheckFlagInRequest || getIdentityScope() == IdentityScope.EUID) { + assertEquals("optout", refreshRespJson.getString("status")); + testContext.completeNow(); + return; + } + + // EUID can't have an opt out token ever + assertEquals(getIdentityScope(), IdentityScope.UID2); + verify(optOutStore, times(2)).getLatestEntry(argumentCaptor.capture()); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), argumentCaptor.getValue().id); @@ -3253,7 +3285,7 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver final AdvertisingToken adTokenFromRefresh = validateAndGetToken(encoder, refreshBody, identityType); final RefreshToken refreshTokenFromRefresh = decodeRefreshToken(encoder, decodeV2RefreshToken(refreshRespJson), identityType); - assertAreClientSideGeneratedOptOutTokens(adTokenFromRefresh, refreshTokenFromRefresh, clientSideTokenGenerateSiteId, identityType); + assertAreClientSideGeneratedOptOutTokens(adTokenFromRefresh, refreshTokenFromRefresh, clientSideTokenGenerateSiteId, identityType, setOptoutCheckFlagInRequest); verifyNoMoreInteractions(optOutStore); @@ -3262,18 +3294,26 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver }); } - // tests for opted out user should lead to generating ad tokens with the default optout identity + // tests for opted out user should lead to generating ad tokens with the default optout identity or optout success response depends on setOptoutCheckFlagInRequest flag // tests for opted in user should lead to generating ad tokens that never match the default optout identity // tests for all email/phone combos @ParameterizedTest - @CsvSource({"true,abc@abc.com,Email,optout@unifiedid.com", - "true,+61400000000,Phone,+00000000001", - "false,abc@abc.com,Email,optout@unifiedid.com", - "false,+61400000000,Phone,+00000000001"}) - void cstgOptedOutTest(boolean optOutExpected, String id, IdentityType identityType, String expectedOptedOutIdentity, + @CsvSource({ + "true,true,abc@abc.com,Email,optout@unifiedid.com", + "true,true,+61400000000,Phone,+00000000001", + "true,false,abc@abc.com,Email,optout@unifiedid.com", + "true,false,+61400000000,Phone,+00000000001", + "false,true,abc@abc.com,Email,optout@unifiedid.com", + "false,true,+61400000000,Phone,+00000000001", + "false,false,abc@abc.com,Email,optout@unifiedid.com", + "false,false,+61400000000,Phone,+00000000001" + }) + void cstgOptedOutTest(boolean setOptoutCheckFlagInRequest, boolean optOutExpected, String id, IdentityType identityType, String expectedOptedOutIdentity, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk"); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli()); + + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); + if(optOutExpected) { when(optOutStore.getLatestEntry(any(UserIdentity.class))) @@ -3292,6 +3332,14 @@ void cstgOptedOutTest(boolean optOutExpected, String id, IdentityType identityTy 200, testContext, respJson -> { + + if (optOutExpected + && (setOptoutCheckFlagInRequest || getIdentityScope() == IdentityScope.EUID)) { + assertEquals("optout", respJson.getString("status")); + testContext.completeNow(); + return; + } + JsonObject genBody = respJson.getJsonObject("body"); assertNotNull(genBody); @@ -3303,9 +3351,9 @@ void cstgOptedOutTest(boolean optOutExpected, String id, IdentityType identityTy RefreshToken refreshToken = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); if (optOutExpected) { - assertAreClientSideGeneratedOptOutTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType); + assertAreClientSideGeneratedOptOutTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, setOptoutCheckFlagInRequest); } else { - assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id, setOptoutCheckFlagInRequest); } assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); @@ -3339,6 +3387,18 @@ else if(identityType == IdentityType.Phone) { //test a subsequent refresh from this cstg call and see if it still works sendTokenRefresh("v2", vertx, testContext, genRefreshToken, genBody.getString("refresh_response_key"), 200, refreshRespJson -> { + + if (optOutExpected + && (setOptoutCheckFlagInRequest || getIdentityScope() == IdentityScope.EUID)) { + fail("Getting a successful optout response for an opted out user with optout check is impossible as the original CSTG request should already gave an optout response and no refresh token should be returned to reach here!"); + return; + } + + // EUID can't have an opt out token - the only way is when optout isn't expected + if(getIdentityScope() == IdentityScope.EUID) { + assert(!optOutExpected); + } + assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); assertNotNull(refreshBody); @@ -3352,9 +3412,9 @@ else if(identityType == IdentityType.Phone) { RefreshToken refreshTokenAfterRefresh = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); if (optOutExpected) { - assertAreClientSideGeneratedOptOutTokens(adTokenFromRefresh, refreshTokenAfterRefresh, clientSideTokenGenerateSiteId, identityType); + assertAreClientSideGeneratedOptOutTokens(adTokenFromRefresh, refreshTokenAfterRefresh, clientSideTokenGenerateSiteId, identityType, setOptoutCheckFlagInRequest); } else { - assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefresh, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefresh, clientSideTokenGenerateSiteId, identityType, id, setOptoutCheckFlagInRequest); } assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); @@ -3371,16 +3431,18 @@ else if(identityType == IdentityType.Phone) { }); } - private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity) { + private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, + boolean expectClientSideTokenGenerateOptoutResponse) { assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, siteId, identityType, identity, - false); + false, + expectClientSideTokenGenerateOptoutResponse); } - private void assertAreClientSideGeneratedOptOutTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType) { + private void assertAreClientSideGeneratedOptOutTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, boolean expectClientSideTokenGenerateOptoutResponse) { final String identity = getClientSideGeneratedTokenOptOutIdentity(identityType); assertAreClientSideGeneratedTokens(advertisingToken, @@ -3388,10 +3450,12 @@ private void assertAreClientSideGeneratedOptOutTokens(AdvertisingToken advertisi siteId, identityType, identity, - true); + true, + expectClientSideTokenGenerateOptoutResponse); } - private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { + private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectedOptOut, + boolean expectClientSideTokenGenerateOptoutResponse) { final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits); final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshToken.userIdentity.privacyBits); @@ -3403,6 +3467,9 @@ private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToke final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(identity, firstLevelSalt); assertAll( + () -> assertEquals(advertisingTokenPrivacyBits.isClientSideTokenGenerateOptoutResponseOn(), expectClientSideTokenGenerateOptoutResponse, "Advertising token privacy bits CSTG Optout Response flag is incorrect"), + () -> assertEquals(refreshTokenPrivacyBits.isClientSideTokenGenerateOptoutResponseOn(), expectClientSideTokenGenerateOptoutResponse, "Refresh token privacy bits CSTG Optout Response flag is incorrect"), + () -> assertTrue(advertisingTokenPrivacyBits.isClientSideTokenGenerated(), "Advertising token privacy bits CSTG flag is incorrect"), () -> assertEquals(expectedOptOut, advertisingTokenPrivacyBits.isClientSideTokenOptedOut(), "Advertising token privacy bits CSTG optout flag is incorrect"), From 23fc603dd8c172e71b62de12fc36b935ecfe5271 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 14 Feb 2024 06:28:52 +0000 Subject: [PATCH 0088/1116] [CI Pipeline] Released Minor version: 5.27.0-d4082509df --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 36f952e6c..28f754b2d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.19-56899dc0d7 + 5.27.0-d4082509df UTF-8 diff --git a/version.json b/version.json index 0b2f114ba..880381b5c 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.26", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.27", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From f7f1948181fa43040fa6a45af71371c5c4fdd7e2 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 14 Feb 2024 16:53:53 +0800 Subject: [PATCH 0089/1116] Reverted pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e1561a31d..53e7f675c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.25.45-SNAPSHOT + 5.25.40-47da1eabb8 UTF-8 From 50e75e61236628bb2fb9665b0c78341fc8a45bb0 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 14 Feb 2024 17:57:08 +0800 Subject: [PATCH 0090/1116] Added AWS Nitro publish workflow --- .../publish-aws-nitro-enclave-docker.yaml | 158 ++++++++++++++++++ Makefile.nitro | 8 +- scripts/aws/pipeline/amazonlinux.Dockerfile | 27 +++ scripts/aws/pipeline/aws_nitro_eif.sh | 13 ++ 4 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/publish-aws-nitro-enclave-docker.yaml create mode 100644 scripts/aws/pipeline/amazonlinux.Dockerfile create mode 100644 scripts/aws/pipeline/aws_nitro_eif.sh diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml new file mode 100644 index 000000000..20f7f39e4 --- /dev/null +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -0,0 +1,158 @@ +name: Publish AWS Nitro Operator +run-name: ${{ format('Publish {0} AWS Nitro Operator', inputs.release_type) }} +on: + workflow_dispatch: + inputs: + release_type: + type: choice + description: 'The type of release' + options: + - Major + - Minor + - Patch + - Snapshot + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + type: string + default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false + workflow_call: + inputs: + release_type: + description: The type of version number to return. Must be one of [Snapshot, Patch, Minor or Major] + required: true + type: string + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + type: string + default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false + + outputs: + image_tag: + description: The tag used to describe the image in docker + value: ${{ jobs.buildImage.outputs.image_tag }} + +env: + ENCLAVE_PROTOCOL: aws-nitro + ARTIFACTS_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts + +jobs: + buildImage: + name: Build Image + runs-on: ubuntu-latest + outputs: + ami_id: ${{ steps.createAMI.outputs.AMI_ID }} + pcr0: ${{ steps.showPCR0.outputs.PCR0 }} + steps: + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + with: + release_type: ${{ inputs.release_type }} + + - name: Show Context + run: | + printenv + echo "$GITHUB_CONTEXT" + shell: bash + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '11' + + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == ''}} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != ''}} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + +# TODO: Assume AWS Identity +# - name: Show AWS Identity +# run: aws sts get-caller-identity + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.2 + + - name: Set version number + id: version + uses: IABTechLab/uid2-shared-actions/actions/version_number@main + with: + type: ${{ inputs.release_type }} + version_number: ${{ inputs.version_number_input }} + branch_name: ${{ github.ref }} + + - name: Update pom.xml + id: updatePom + run: | + current_version=$(grep -o '.*' pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/') + new_version=${{ steps.version.outputs.new_version }} + sed -i "0,/$current_version/s/$current_version/$new_version/" pom.xml + echo "Version number updated from $current_version to $new_version" + echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT + + - name: Commit pom.xml and version.json + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + + - name: Commit pom.xml, version.json and set tag + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + tag: v${{ steps.version.outputs.new_version }} + + - name: Run amazonlinux Docker image + run: | + docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . + docker run -d --privileged --name amazonlinux amazonlinux:latest + + - name: Build UID2 AWS Nitro EIF + run: | + make -f Makefile.nitro uid2operator.eif + docker cp amazonlinux:/uid2operator.eif ./build/uid2operator.eif + + - name: Build EUID AWS Nitro EIF + run: | + make -f Makefile.nitro euidoperator.eif + docker cp amazonlinux:/euidoperator.eif ./build/euidoperator.eif + + - name: Prepare artifacts + run: | + mkdir -p artifacts + cp ./build/uid2operator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2operator.eif + cp ./build/euidoperator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/euidoperator.eif + + - uses: actions/upload-artifact@v3 + with: + name: aws-nitro-deployment-files + path: | + ${{ env.ARTIFACTS_OUTPUT_DIR }} \ No newline at end of file diff --git a/Makefile.nitro b/Makefile.nitro index 70ed5e0f1..b4fabf42b 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -36,12 +36,12 @@ clean: build_eif: uid2operator.eif euidoperator.eif euidoperator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py - cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; - cd build; nitro-cli build-enclave --docker-uri euidoperator --output-file euidoperator.eif + cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./euidoperator.tar euidoperator; docker cp ./euidoperator.tar amazonlinux:/euidoperator.tar + docker exec amazonlinux bash aws_nitro_eif.sh euidoperator uid2operator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py - cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; - cd build; nitro-cli build-enclave --docker-uri uid2operator --output-file uid2operator.eif + cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./uid2operator.tar uid2operator; docker cp ./uid2operator.tar amazonlinux:/uid2operator.tar + docker exec amazonlinux bash aws_nitro_eif.sh uid2operator build/load_config.py: ./scripts/aws/load_config.py cp ./scripts/aws/load_config.py ./build/ diff --git a/scripts/aws/pipeline/amazonlinux.Dockerfile b/scripts/aws/pipeline/amazonlinux.Dockerfile new file mode 100644 index 000000000..a09ab1843 --- /dev/null +++ b/scripts/aws/pipeline/amazonlinux.Dockerfile @@ -0,0 +1,27 @@ +# https://gist.github.com/toricls/e17c7f2f1c024cc368dcd860804194f5 +FROM amazonlinux:2 + +RUN yum -y update + # systemd is not a hard requirement for Amazon ECS Anywhere, but the installation script currently only supports systemd to run. + # Amazon ECS Anywhere can be used without systemd, if you set up your nodes and register them into your ECS cluster **without** the installation script. +RUN yum -y install systemd +RUN yum clean all + +RUN cd /lib/systemd/system/sysinit.target.wants/; \ + for i in *; do [ $i = systemd-tmpfiles-setup.service ] || rm -f $i; done +RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ + /etc/systemd/system/*.wants/* \ + /lib/systemd/system/local-fs.target.wants/* \ + /lib/systemd/system/sockets.target.wants/*udev* \ + /lib/systemd/system/sockets.target.wants/*initctl* \ + /lib/systemd/system/basic.target.wants/* \ + /lib/systemd/system/anaconda.target.wants/* + +RUN amazon-linux-extras install -y epel docker aws-nitro-enclaves-cli +RUN yum -y install aws-nitro-enclaves-cli-devel + +RUN systemctl enable docker + +COPY ./aws/pipeline/aws_nitro_eif.sh /aws_nitro_eif.sh + +CMD ["/usr/sbin/init"] diff --git a/scripts/aws/pipeline/aws_nitro_eif.sh b/scripts/aws/pipeline/aws_nitro_eif.sh new file mode 100644 index 000000000..7a7aacaa2 --- /dev/null +++ b/scripts/aws/pipeline/aws_nitro_eif.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -x + +dockerd & +while (! docker stats --no-stream >/dev/null 2>&1); do + # Docker takes a few seconds to initialize + echo -n "." + sleep 1 +done + +docker load -i /$1.tar +nitro-cli build-enclave --docker-uri $1 --output-file $1.eif From c3bdbf0eb08f5c0eb15706771f26109b9d64d990 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 14 Feb 2024 17:57:50 +0800 Subject: [PATCH 0091/1116] Updated publish operator image formatting --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 10 +++++----- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 10 +++++----- .../publish-public-operator-docker-image.yaml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 01a317a63..f719eda24 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -33,12 +33,12 @@ on: description: If true, will skip the step for E2E tests type: boolean default: false - + outputs: image_tag: - description: The tag used to describe the image in docker + description: The tag used to describe the image in Docker value: ${{ jobs.buildImage.outputs.image_tag }} - + env: REGISTRY: ghcr.io MAVEN_PROFILE: azure @@ -74,7 +74,7 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - + - name: Set up JDK uses: actions/setup-java@v3 with: @@ -249,7 +249,7 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip - + e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 27591bb6d..b08bd2930 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -33,12 +33,12 @@ on: description: If true, will skip the step for E2E tests type: boolean default: false - + outputs: image_tag: - description: The tag used to describe the image in docker + description: The tag used to describe the image in Docker value: ${{ jobs.buildImage.outputs.image_tag }} - + env: REGISTRY: ghcr.io GCP_REGISTRY: us-docker.pkg.dev @@ -76,7 +76,7 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - + - name: Set up JDK uses: actions/setup-java@v3 with: @@ -286,7 +286,7 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip - + e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 839451afc..0b231bfbc 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -29,7 +29,7 @@ on: outputs: image_tag: - description: The tag used to describe the image in docker + description: The tag used to describe the image in Docker value: ${{ jobs.Image.outputs.image_tag }} jobs: From 89ac0ec5f941c606c0bc37f4972f8ab90f6ed8c9 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 14 Feb 2024 17:59:11 +0800 Subject: [PATCH 0092/1116] Added AWS cred config in AWS publish pipeline --- .../workflows/publish-aws-nitro-enclave-docker.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 20f7f39e4..ef6c459d8 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -87,9 +87,13 @@ jobs: # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. fetch-depth: 0 -# TODO: Assume AWS Identity -# - name: Show AWS Identity -# run: aws sts get-caller-identity + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-2 + role-to-assume: arn:aws:iam::072245134533:role/github-runner-for-uid2-operator + - run: aws sts get-caller-identity + shell: bash - name: Restore timestamps uses: thetradedesk/git-restore-mtime-action@v1.2 @@ -155,4 +159,4 @@ jobs: with: name: aws-nitro-deployment-files path: | - ${{ env.ARTIFACTS_OUTPUT_DIR }} \ No newline at end of file + ${{ env.ARTIFACTS_OUTPUT_DIR }} From 8ffcc2f4210523997ce7e6cb2e151f65dd5ac9fb Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 15 Feb 2024 09:26:37 +1100 Subject: [PATCH 0093/1116] Temporary config changes for AWS AMI to test locally --- pom.xml | 2 +- scripts/aws/conf/integ-uid2-config.json | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 36f952e6c..ebcd903b8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.19-56899dc0d7 + 5.26.21-SNAPSHOT UTF-8 diff --git a/scripts/aws/conf/integ-uid2-config.json b/scripts/aws/conf/integ-uid2-config.json index a7272a26a..7d9bcea40 100644 --- a/scripts/aws/conf/integ-uid2-config.json +++ b/scripts/aws/conf/integ-uid2-config.json @@ -1,15 +1,15 @@ { - "sites_metadata_path": "https://core-integ.uidapi.com/sites/refresh", - "clients_metadata_path": "https://core-integ.uidapi.com/clients/refresh", - "keysets_metadata_path": "https://core-integ.uidapi.com/key/keyset/refresh", - "keyset_keys_metadata_path": "https://core-integ.uidapi.com/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://core-integ.uidapi.com/client_side_keypairs/refresh", - "salts_metadata_path": "https://core-integ.uidapi.com/salt/refresh", - "services_metadata_path": "https://core-integ.uidapi.com/services/refresh", - "service_links_metadata_path": "https://core-integ.uidapi.com/service_links/refresh", - "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", - "core_attest_url": "https://core-integ.uidapi.com/attest", - "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", + "sites_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/sites/refresh", + "clients_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/clients/refresh", + "keysets_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset/refresh", + "keyset_keys_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/client_side_keypairs/refresh", + "salts_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/salt/refresh", + "services_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/services/refresh", + "service_links_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/service_links/refresh", + "optout_metadata_path": "https://21db-113-29-30-226.ngrok-free.app/optout/refresh", + "core_attest_url": "https://b8ce-113-29-30-226.ngrok-free.app/attest", + "optout_api_uri": "https://21db-113-29-30-226.ngrok-free.app/optout/replicate", "optout_s3_folder": "uid-optout-integ/", "allow_legacy_api": false } From c6af59697a12356bbabd49719a928e78f09caad6 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 15 Feb 2024 16:05:48 +1100 Subject: [PATCH 0094/1116] Use snapshot versions for adding url to user data --- pom.xml | 20 ++++++++++++---- scripts/gcp-oidc/conf/integ-uid2-config.json | 24 ++++++++++---------- scripts/gcp-oidc/entrypoint.sh | 22 ++++++++++-------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/pom.xml b/pom.xml index ebcd903b8..da71ea5d3 100644 --- a/pom.xml +++ b/pom.xml @@ -18,14 +18,24 @@ com.uid2.operator.vertx.UIDOperatorVerticle 1.1.0 - 1.5.0-676519b018 - 1.1.0 - 1.5.0-115595d597 - 1.4.2-dd1920710d - 6.1.8-6e6866128b + 1.6.10-SNAPSHOT + 1.1.15-SNAPSHOT + 1.5.25-SNAPSHOT + 1.4.15-SNAPSHOT + 6.1.9-SNAPSHOT ${project.version} + + + + snapshots-repo + https://s01.oss.sonatype.org/content/repositories/snapshots + false + true + + + com.google.guava diff --git a/scripts/gcp-oidc/conf/integ-uid2-config.json b/scripts/gcp-oidc/conf/integ-uid2-config.json index 2dd489960..9e80b9ddf 100644 --- a/scripts/gcp-oidc/conf/integ-uid2-config.json +++ b/scripts/gcp-oidc/conf/integ-uid2-config.json @@ -1,15 +1,15 @@ { - "sites_metadata_path": "https://core-integ.uidapi.com/sites/refresh", - "clients_metadata_path": "https://core-integ.uidapi.com/clients/refresh", - "keysets_metadata_path": "https://core-integ.uidapi.com/key/keyset/refresh", - "keyset_keys_metadata_path": "https://core-integ.uidapi.com/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://core-integ.uidapi.com/client_side_keypairs/refresh", - "salts_metadata_path": "https://core-integ.uidapi.com/salt/refresh", - "services_metadata_path": "https://core-integ.uidapi.com/services/refresh", - "service_links_metadata_path": "https://core-integ.uidapi.com/service_links/refresh", - "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", - "core_attest_url": "https://core-integ.uidapi.com/attest", - "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", + "sites_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/sites/refresh", + "clients_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/clients/refresh", + "keysets_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset/refresh", + "keyset_keys_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/client_side_keypairs/refresh", + "salts_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/salt/refresh", + "services_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/services/refresh", + "service_links_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/service_links/refresh", + "optout_metadata_path": "https://21db-113-29-30-226.ngrok-free.app/optout/refresh", + "core_attest_url": "https://b8ce-113-29-30-226.ngrok-free.app/attest", + "optout_api_uri": "https://21db-113-29-30-226.ngrok-free.app/optout/replicate", "optout_s3_folder": "uid-optout-integ/", - "enforce_https": true + "enforce_https": false } diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index 08effd77f..079d54047 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -47,18 +47,20 @@ fi # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently -#if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then -# echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" -# sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} +if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then + echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" + sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} -# sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} -#fi + sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} + + # -- replace `enforce_https` value to ENFORCE_HTTPS if provided + if [ "${ENFORCE_HTTPS}" == false ]; then + echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" + jq_inplace_update_json $FINAL_CONFIG enforce_https false + fi + +fi -# -- replace `enforce_https` value to ENFORCE_HTTPS if provided -#if [ "${ENFORCE_HTTPS}" == false ]; then -# echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" -# jq_inplace_update_json $FINAL_CONFIG enforce_https false -#fi cat $FINAL_CONFIG From fe3beb1ac4ed7738d81276c85cc69a23d006b5bb Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 15 Feb 2024 16:19:12 +1100 Subject: [PATCH 0095/1116] Use Shared snapshot --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index da71ea5d3..bf07d1902 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 1.1.15-SNAPSHOT 1.5.25-SNAPSHOT 1.4.15-SNAPSHOT - 6.1.9-SNAPSHOT + 6.1.8-SNAPSHOT ${project.version} From d5ac5e0e6bd96b44d2797a7b8989259ff8968fa8 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 15 Feb 2024 20:13:49 +1100 Subject: [PATCH 0096/1116] Updating shared --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bf07d1902..9e904dd90 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 1.1.15-SNAPSHOT 1.5.25-SNAPSHOT 1.4.15-SNAPSHOT - 6.1.8-SNAPSHOT + 6.1.10-SNAPSHOT ${project.version} From 72ed4511532a11e4134a5a90205f1bbe4256b7cc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 19 Feb 2024 10:15:43 +1100 Subject: [PATCH 0097/1116] Remove enforce_https --- conf/local-e2e-docker-private-config.json | 1 - conf/local-e2e-docker-public-config.json | 1 - conf/local-e2e-private-config.json | 1 - conf/local-e2e-public-config.json | 1 - pom.xml | 10 ++++---- scripts/azure-cc/conf/default-config.json | 1 - scripts/azure-cc/conf/integ-uid2-config.json | 1 - scripts/azure-cc/deployment/operator.json | 10 -------- scripts/azure-cc/entrypoint.sh | 26 ++++---------------- scripts/gcp-oidc/conf/default-config.json | 1 - scripts/gcp-oidc/conf/integ-uid2-config.json | 3 +-- scripts/gcp-oidc/entrypoint.sh | 18 -------------- scripts/gcp/README.md | 1 - scripts/gcp/conf/integ-config.json | 1 - scripts/gcp/conf/prod-config.json | 1 - src/main/java/com/uid2/operator/Main.java | 5 ++-- 16 files changed, 13 insertions(+), 69 deletions(-) diff --git a/conf/local-e2e-docker-private-config.json b/conf/local-e2e-docker-private-config.json index b39a102bd..20b2ebb1a 100644 --- a/conf/local-e2e-docker-private-config.json +++ b/conf/local-e2e-docker-private-config.json @@ -1,7 +1,6 @@ { "service_instances": 1, "storage_mock": false, - "enforce_https": false, "core_attest_url": "http://core:8088/attest", "core_api_token": "OPLCLAjLRWcVlCDl9+BbwR38gzxYdiWFa751ynWLuI7JU4iA=", "sites_metadata_path": "http://core:8088/sites/refresh", diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index 87b042c7b..fd0146fe5 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -1,7 +1,6 @@ { "service_instances": 1, "storage_mock": false, - "enforce_https": false, "core_attest_url": "http://core:8088/attest", "core_api_token": "UID2-O-L-999-dp9Dt0.JVoGpynN4J8nMA7FxmzsavxJa8B9H74y9xdEE=", "sites_metadata_path": "http://core:8088/sites/refresh", diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index eba8acd1f..763231bd2 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -1,7 +1,6 @@ { "service_instances": 1, "storage_mock": true, - "enforce_https": false, "core_attest_url": "http://localhost:8088/attest", "core_api_token": "OPLCLAjLRWcVlCDl9+BbwR38gzxYdiWFa751ynWLuI7JU4iA=", "sites_metadata_path": "http://localhost:8088/sites/refresh", diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index aed23ed8e..684ef73d6 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -1,7 +1,6 @@ { "service_instances": 1, "storage_mock": true, - "enforce_https": false, "core_attest_url": "http://localhost:8088/attest", "core_api_token": "UID2-O-L-999-dp9Dt0.JVoGpynN4J8nMA7FxmzsavxJa8B9H74y9xdEE=", "sites_metadata_path": "http://localhost:8088/sites/refresh", diff --git a/pom.xml b/pom.xml index 9e904dd90..be60d719d 100644 --- a/pom.xml +++ b/pom.xml @@ -18,11 +18,11 @@ com.uid2.operator.vertx.UIDOperatorVerticle 1.1.0 - 1.6.10-SNAPSHOT - 1.1.15-SNAPSHOT - 1.5.25-SNAPSHOT - 1.4.15-SNAPSHOT - 6.1.10-SNAPSHOT + 2.0.0-f968aec0e3 + 2.0.0-f7c174410e + 2.0.4-ef52553c57 + 2.0.0-21f950573a + 6.1.17-SNAPSHOT ${project.version} diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index 0464ed92d..c0684b85f 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -34,7 +34,6 @@ "identity_token_expires_after_seconds": 86400, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, - "enforce_https": true, "allow_legacy_api": false, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, diff --git a/scripts/azure-cc/conf/integ-uid2-config.json b/scripts/azure-cc/conf/integ-uid2-config.json index 77828b385..ac8263034 100644 --- a/scripts/azure-cc/conf/integ-uid2-config.json +++ b/scripts/azure-cc/conf/integ-uid2-config.json @@ -11,5 +11,4 @@ "core_attest_url": "https://core-integ.uidapi.com/attest", "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", "optout_s3_folder": "uid-optout-integ/", - "enforce_https": true } diff --git a/scripts/azure-cc/deployment/operator.json b/scripts/azure-cc/deployment/operator.json index eb1ae295f..14ab9531d 100644 --- a/scripts/azure-cc/deployment/operator.json +++ b/scripts/azure-cc/deployment/operator.json @@ -54,12 +54,6 @@ "metadata": { "description": "Operator Key" } - }, - "enforceHttps": { - "type": "bool", - "metadata": { - "description": "Whether to use HTTPS to communicate with core and optout service" - } } }, "variables": { @@ -124,10 +118,6 @@ { "name": "DEPLOYMENT_ENVIRONMENT", "value": "[parameters('deploymentEnvironment')]" - }, - { - "name": "ENFORCE_HTTPS", - "value": "[parameters('enforceHttps')]" } ] } diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index 286eedd84..5a2afc4ec 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -4,16 +4,6 @@ TMP_FINAL_CONFIG="/tmp/final-config.tmp" -# for number/boolean -# https://jqlang.github.io/jq/manual/ -# --argjson foo 123 will bind $foo to 123. -function jq_inplace_update_json() { - local file=$1 - local field=$2 - local value=$3 - jq --argjson v "$value" ".$field = \$v" "$file" > $TMP_FINAL_CONFIG && mv $TMP_FINAL_CONFIG "$file" -} - if [ -z "${VAULT_NAME}" ]; then echo "VAULT_NAME cannot be empty" exit 1 @@ -53,18 +43,12 @@ fi # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently -#if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then -# echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" -# sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} -# -# sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} -#fi +if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then + echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" + sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} -# -- replace `enforce_https` value to ENFORCE_HTTPS if provided -#if [ "${ENFORCE_HTTPS}" == false ]; then -# echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" -# jq_inplace_update_json $FINAL_CONFIG enforce_https false -#fi + sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} +fi cat $FINAL_CONFIG diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index 91a1b38e6..c744175a2 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -34,7 +34,6 @@ "identity_token_expires_after_seconds": 86400, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, - "enforce_https": true, "allow_legacy_api": false, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, diff --git a/scripts/gcp-oidc/conf/integ-uid2-config.json b/scripts/gcp-oidc/conf/integ-uid2-config.json index 9e80b9ddf..99e0790e7 100644 --- a/scripts/gcp-oidc/conf/integ-uid2-config.json +++ b/scripts/gcp-oidc/conf/integ-uid2-config.json @@ -10,6 +10,5 @@ "optout_metadata_path": "https://21db-113-29-30-226.ngrok-free.app/optout/refresh", "core_attest_url": "https://b8ce-113-29-30-226.ngrok-free.app/attest", "optout_api_uri": "https://21db-113-29-30-226.ngrok-free.app/optout/replicate", - "optout_s3_folder": "uid-optout-integ/", - "enforce_https": false + "optout_s3_folder": "uid-optout-integ/" } diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index 079d54047..8ae25914b 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -2,17 +2,6 @@ # # This script must be compatible with Ash (provided in eclipse-temurin Docker image) and Bash -# for number/boolean -# https://jqlang.github.io/jq/manual/ -# --argjson foo 123 will bind $foo to 123. -function jq_inplace_update_json() { - local file=$1 - local field=$2 - local value=$3 - jq --argjson v "$value" ".$field = \$v" "$file" > tmp.json && mv tmp.json "$file" -} - - # -- set API tokens if [ -z "${API_TOKEN_SECRET_NAME}" ]; then echo "API_TOKEN_SECRET_NAME cannot be empty" @@ -52,13 +41,6 @@ if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONME sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} - - # -- replace `enforce_https` value to ENFORCE_HTTPS if provided - if [ "${ENFORCE_HTTPS}" == false ]; then - echo "-- replacing enforce_https by ${ENFORCE_HTTPS}" - jq_inplace_update_json $FINAL_CONFIG enforce_https false - fi - fi diff --git a/scripts/gcp/README.md b/scripts/gcp/README.md index 4e939ff3b..8846f67cd 100644 --- a/scripts/gcp/README.md +++ b/scripts/gcp/README.md @@ -130,7 +130,6 @@ write_files: "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", - "enforce_https": true, "service_instances": 16, "allow_legacy_api": false } diff --git a/scripts/gcp/conf/integ-config.json b/scripts/gcp/conf/integ-config.json index 6ca522524..7223450e5 100644 --- a/scripts/gcp/conf/integ-config.json +++ b/scripts/gcp/conf/integ-config.json @@ -12,7 +12,6 @@ "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", - "enforce_https": true, "service_instances": 16, "allow_legacy_api": false, "sharing_token_expiry_seconds": 2592000 diff --git a/scripts/gcp/conf/prod-config.json b/scripts/gcp/conf/prod-config.json index 21158af6e..17f85276b 100644 --- a/scripts/gcp/conf/prod-config.json +++ b/scripts/gcp/conf/prod-config.json @@ -12,7 +12,6 @@ "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", - "enforce_https": true, "service_instances": 16, "allow_legacy_api": false, "sharing_token_expiry_seconds": 2592000 diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index 5eb756875..d10fda7a9 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -453,9 +453,8 @@ public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticC private Map.Entry createUidClients(Vertx vertx, String attestationUrl, String clientApiToken, Handler> responseWatcher) throws Exception { AttestationTokenRetriever attestationTokenRetriever = getAttestationTokenRetriever(vertx, attestationUrl, clientApiToken, responseWatcher); - Boolean enforceHttps = this.config.getBoolean("enforce_https", true); - UidCoreClient coreClient = new UidCoreClient(clientApiToken, CloudUtils.defaultProxy, enforceHttps, attestationTokenRetriever); - UidOptOutClient optOutClient = new UidOptOutClient(clientApiToken, CloudUtils.defaultProxy, enforceHttps, attestationTokenRetriever); + UidCoreClient coreClient = new UidCoreClient(clientApiToken, CloudUtils.defaultProxy, attestationTokenRetriever); + UidOptOutClient optOutClient = new UidOptOutClient(clientApiToken, CloudUtils.defaultProxy, attestationTokenRetriever); return new AbstractMap.SimpleEntry<>(coreClient, optOutClient); } From a8919c33ff1bb4e0af6c3537151c7c06d83c580e Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 19 Feb 2024 10:27:09 +1100 Subject: [PATCH 0098/1116] Updated shared --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be60d719d..a768d855f 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 6.1.17-SNAPSHOT + 6.1.19-SNAPSHOT ${project.version} From bfb9620263a69b1c553f5e3cdef9234e78d83f3b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 19 Feb 2024 12:07:55 +1100 Subject: [PATCH 0099/1116] Change ngrok address --- scripts/aws/conf/integ-uid2-config.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/aws/conf/integ-uid2-config.json b/scripts/aws/conf/integ-uid2-config.json index 7d9bcea40..0b51e83fb 100644 --- a/scripts/aws/conf/integ-uid2-config.json +++ b/scripts/aws/conf/integ-uid2-config.json @@ -1,15 +1,15 @@ { - "sites_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/sites/refresh", - "clients_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/clients/refresh", - "keysets_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset/refresh", - "keyset_keys_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/client_side_keypairs/refresh", - "salts_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/salt/refresh", - "services_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/services/refresh", - "service_links_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/service_links/refresh", - "optout_metadata_path": "https://21db-113-29-30-226.ngrok-free.app/optout/refresh", - "core_attest_url": "https://b8ce-113-29-30-226.ngrok-free.app/attest", - "optout_api_uri": "https://21db-113-29-30-226.ngrok-free.app/optout/replicate", + "sites_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/sites/refresh", + "clients_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/clients/refresh", + "keysets_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/key/keyset/refresh", + "keyset_keys_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/client_side_keypairs/refresh", + "salts_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/salt/refresh", + "services_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/services/refresh", + "service_links_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/service_links/refresh", + "optout_metadata_path": "https://99ef-113-29-30-226.ngrok-free.app/optout/refresh", + "core_attest_url": "https://ade7-113-29-30-226.ngrok-free.app/attest", + "optout_api_uri": "https://99ef-113-29-30-226.ngrok-free.app/optout/replicate", "optout_s3_folder": "uid-optout-integ/", "allow_legacy_api": false } From 05b56c49838998a415a94b32254296760f08958f Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 19 Feb 2024 13:51:17 +1100 Subject: [PATCH 0100/1116] Revert the config changes for integ --- scripts/aws/conf/integ-uid2-config.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/aws/conf/integ-uid2-config.json b/scripts/aws/conf/integ-uid2-config.json index 0b51e83fb..a7272a26a 100644 --- a/scripts/aws/conf/integ-uid2-config.json +++ b/scripts/aws/conf/integ-uid2-config.json @@ -1,15 +1,15 @@ { - "sites_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/sites/refresh", - "clients_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/clients/refresh", - "keysets_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/key/keyset/refresh", - "keyset_keys_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/client_side_keypairs/refresh", - "salts_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/salt/refresh", - "services_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/services/refresh", - "service_links_metadata_path": "https://ade7-113-29-30-226.ngrok-free.app/service_links/refresh", - "optout_metadata_path": "https://99ef-113-29-30-226.ngrok-free.app/optout/refresh", - "core_attest_url": "https://ade7-113-29-30-226.ngrok-free.app/attest", - "optout_api_uri": "https://99ef-113-29-30-226.ngrok-free.app/optout/replicate", + "sites_metadata_path": "https://core-integ.uidapi.com/sites/refresh", + "clients_metadata_path": "https://core-integ.uidapi.com/clients/refresh", + "keysets_metadata_path": "https://core-integ.uidapi.com/key/keyset/refresh", + "keyset_keys_metadata_path": "https://core-integ.uidapi.com/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://core-integ.uidapi.com/client_side_keypairs/refresh", + "salts_metadata_path": "https://core-integ.uidapi.com/salt/refresh", + "services_metadata_path": "https://core-integ.uidapi.com/services/refresh", + "service_links_metadata_path": "https://core-integ.uidapi.com/service_links/refresh", + "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", + "core_attest_url": "https://core-integ.uidapi.com/attest", + "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", "optout_s3_folder": "uid-optout-integ/", "allow_legacy_api": false } From 7ae81e1626f1fa3c7c9fa7730c1c28a549000b50 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 19 Feb 2024 13:53:58 +1100 Subject: [PATCH 0101/1116] Reverting gcp config --- scripts/gcp-oidc/conf/integ-uid2-config.json | 25 ++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/scripts/gcp-oidc/conf/integ-uid2-config.json b/scripts/gcp-oidc/conf/integ-uid2-config.json index 99e0790e7..2dd489960 100644 --- a/scripts/gcp-oidc/conf/integ-uid2-config.json +++ b/scripts/gcp-oidc/conf/integ-uid2-config.json @@ -1,14 +1,15 @@ { - "sites_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/sites/refresh", - "clients_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/clients/refresh", - "keysets_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset/refresh", - "keyset_keys_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/client_side_keypairs/refresh", - "salts_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/salt/refresh", - "services_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/services/refresh", - "service_links_metadata_path": "https://b8ce-113-29-30-226.ngrok-free.app/service_links/refresh", - "optout_metadata_path": "https://21db-113-29-30-226.ngrok-free.app/optout/refresh", - "core_attest_url": "https://b8ce-113-29-30-226.ngrok-free.app/attest", - "optout_api_uri": "https://21db-113-29-30-226.ngrok-free.app/optout/replicate", - "optout_s3_folder": "uid-optout-integ/" + "sites_metadata_path": "https://core-integ.uidapi.com/sites/refresh", + "clients_metadata_path": "https://core-integ.uidapi.com/clients/refresh", + "keysets_metadata_path": "https://core-integ.uidapi.com/key/keyset/refresh", + "keyset_keys_metadata_path": "https://core-integ.uidapi.com/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://core-integ.uidapi.com/client_side_keypairs/refresh", + "salts_metadata_path": "https://core-integ.uidapi.com/salt/refresh", + "services_metadata_path": "https://core-integ.uidapi.com/services/refresh", + "service_links_metadata_path": "https://core-integ.uidapi.com/service_links/refresh", + "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", + "core_attest_url": "https://core-integ.uidapi.com/attest", + "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", + "optout_s3_folder": "uid-optout-integ/", + "enforce_https": true } From 10219ff262a21685cab3fc5a6188f38c8912da36 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 19 Feb 2024 18:22:56 +0800 Subject: [PATCH 0102/1116] Added PCR0 output --- .../publish-aws-nitro-enclave-docker.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ef6c459d8..8c35a5cd9 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -35,9 +35,9 @@ on: default: false outputs: - image_tag: - description: The tag used to describe the image in docker - value: ${{ jobs.buildImage.outputs.image_tag }} + pcr0: + description: The EIF PCR0 + value: ${{ jobs.buildImage.outputs.pcr0 }} env: ENCLAVE_PROTOCOL: aws-nitro @@ -48,7 +48,6 @@ jobs: name: Build Image runs-on: ubuntu-latest outputs: - ami_id: ${{ steps.createAMI.outputs.AMI_ID }} pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: - name: Check branch and release type @@ -139,21 +138,22 @@ jobs: docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . docker run -d --privileged --name amazonlinux amazonlinux:latest - - name: Build UID2 AWS Nitro EIF + - name: Build AWS Nitro EIF run: | make -f Makefile.nitro uid2operator.eif docker cp amazonlinux:/uid2operator.eif ./build/uid2operator.eif - - name: Build EUID AWS Nitro EIF + - name: Show PCR0 + id: showPCR0 run: | - make -f Makefile.nitro euidoperator.eif - docker cp amazonlinux:/euidoperator.eif ./build/euidoperator.eif + PCR0=$(nitro-cli describe-eif --eif-path uid2operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) + echo "PCR0: " $PCR0 + echo "PCR0=$PCR0" >> $GITHUB_OUTPUT - name: Prepare artifacts run: | mkdir -p artifacts cp ./build/uid2operator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2operator.eif - cp ./build/euidoperator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/euidoperator.eif - uses: actions/upload-artifact@v3 with: From 8a0a9ab096dce2407129b46623d6e7ebb83ee11e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 19 Feb 2024 18:26:59 +0800 Subject: [PATCH 0103/1116] Added dante and vsockpx artifacts --- .../publish-aws-nitro-enclave-docker.yaml | 34 +++++++++++++++++-- scripts/aws/pipeline/VERSION | 1 + 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 scripts/aws/pipeline/VERSION diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 8c35a5cd9..6e26929fb 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -150,10 +150,40 @@ jobs: echo "PCR0: " $PCR0 echo "PCR0=$PCR0" >> $GITHUB_OUTPUT + - name: Download dante + run: | + wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz + echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum + sha256sum --check dante_checksum + tar -xf dante-1.4.3.tar.gz + + - name: Make dante + working-directory: ./dante-1.4.3 + run: | + ./configure + make + + - name: Make vsockpx for Amazon Linux 2 + run: | + git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git + mkdir uid2-aws-enclave-vsockproxy/build + cd uid2-aws-enclave-vsockproxy/build + cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo + make + - name: Prepare artifacts run: | - mkdir -p artifacts - cp ./build/uid2operator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2operator.eif + mkdir -p ${{ env.ARTIFACTS_OUTPUT_DIR }} + cp ./dante-1.4.3/sockd/sockd ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./build/uid2operator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./scripts/aws/start.sh ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./scripts/aws/stop.sh ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./scripts/aws/proxies.host.yaml ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./scripts/aws/sockd.conf ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./scripts/aws/uid2operator.service ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./scripts/aws/pipeline/VERSION ${{ env.ARTIFACTS_OUTPUT_DIR }}/ + cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${{ env.ARTIFACTS_OUTPUT_DIR }}/vsockpx + echo "UID2" >> ${{ env.ARTIFACTS_OUTPUT_DIR }}/identity_scope - uses: actions/upload-artifact@v3 with: diff --git a/scripts/aws/pipeline/VERSION b/scripts/aws/pipeline/VERSION new file mode 100644 index 000000000..7296f257e --- /dev/null +++ b/scripts/aws/pipeline/VERSION @@ -0,0 +1 @@ +136 From 48982d2bf807aace8d82c5ff42b28dac2540f826 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 20 Feb 2024 15:20:18 +1100 Subject: [PATCH 0104/1116] Allow the specification of the Core URL for GCP --- pom.xml | 4 ++-- scripts/gcp-oidc/Dockerfile | 2 +- scripts/gcp-oidc/conf/integ-uid2-config.json | 25 ++++++++++---------- scripts/gcp-oidc/conf/prod-uid2-config.json | 22 ++++++++--------- scripts/gcp-oidc/entrypoint.sh | 19 ++++++++++----- scripts/gcp-oidc/terraform/main.tf | 2 ++ 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index a768d855f..bc4433f7a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.26.21-SNAPSHOT + 5.26.24-SNAPSHOT UTF-8 @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 6.1.19-SNAPSHOT + 7.0.0-b264db84a3 ${project.version} diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 15d775838..1da22360d 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d -LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT" +LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL" # Install Packages RUN apk update && apk add jq diff --git a/scripts/gcp-oidc/conf/integ-uid2-config.json b/scripts/gcp-oidc/conf/integ-uid2-config.json index 2dd489960..935514b5a 100644 --- a/scripts/gcp-oidc/conf/integ-uid2-config.json +++ b/scripts/gcp-oidc/conf/integ-uid2-config.json @@ -1,15 +1,14 @@ { - "sites_metadata_path": "https://core-integ.uidapi.com/sites/refresh", - "clients_metadata_path": "https://core-integ.uidapi.com/clients/refresh", - "keysets_metadata_path": "https://core-integ.uidapi.com/key/keyset/refresh", - "keyset_keys_metadata_path": "https://core-integ.uidapi.com/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://core-integ.uidapi.com/client_side_keypairs/refresh", - "salts_metadata_path": "https://core-integ.uidapi.com/salt/refresh", - "services_metadata_path": "https://core-integ.uidapi.com/services/refresh", - "service_links_metadata_path": "https://core-integ.uidapi.com/service_links/refresh", - "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", - "core_attest_url": "https://core-integ.uidapi.com/attest", - "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", - "optout_s3_folder": "uid-optout-integ/", - "enforce_https": true + "sites_metadata_path": "https://core.uidapi.com/sites/refresh", + "clients_metadata_path": "https://core.uidapi.com/clients/refresh", + "keysets_metadata_path": "https://core.uidapi.com/key/keyset/refresh", + "keyset_keys_metadata_path": "https://core.uidapi.com/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://core.uidapi.com/client_side_keypairs/refresh", + "salts_metadata_path": "https://core.uidapi.com/salt/refresh", + "services_metadata_path": "https://core.uidapi.com/services/refresh", + "service_links_metadata_path": "https://core.uidapi.com/service_links/refresh", + "optout_metadata_path": "https://optout.uidapi.com/optout/refresh", + "core_attest_url": "https://core.uidapi.com/attest", + "optout_api_uri": "https://optout.uidapi.com/optout/replicate", + "optout_s3_folder": "uid-optout-integ/" } diff --git a/scripts/gcp-oidc/conf/prod-uid2-config.json b/scripts/gcp-oidc/conf/prod-uid2-config.json index 6de8b0674..f5445a9ec 100644 --- a/scripts/gcp-oidc/conf/prod-uid2-config.json +++ b/scripts/gcp-oidc/conf/prod-uid2-config.json @@ -1,15 +1,15 @@ { - "sites_metadata_path": "https://core-prod.uidapi.com/sites/refresh", - "clients_metadata_path": "https://core-prod.uidapi.com/clients/refresh", - "keysets_metadata_path": "https://core-prod.uidapi.com/key/keyset/refresh", - "keyset_keys_metadata_path": "https://core-prod.uidapi.com/key/keyset-keys/refresh", - "client_side_keypairs_metadata_path": "https://core-prod.uidapi.com/client_side_keypairs/refresh", - "salts_metadata_path": "https://core-prod.uidapi.com/salt/refresh", - "services_metadata_path": "https://core-prod.uidapi.com/services/refresh", - "service_links_metadata_path": "https://core-prod.uidapi.com/service_links/refresh", - "optout_metadata_path": "https://optout-prod.uidapi.com/optout/refresh", - "core_attest_url": "https://core-prod.uidapi.com/attest", - "optout_api_uri": "https://optout-prod.uidapi.com/optout/replicate", + "sites_metadata_path": "https://core.uidapi.com/sites/refresh", + "clients_metadata_path": "https://core.uidapi.com/clients/refresh", + "keysets_metadata_path": "https://core.uidapi.com/key/keyset/refresh", + "keyset_keys_metadata_path": "https://core.uidapi.com/key/keyset-keys/refresh", + "client_side_keypairs_metadata_path": "https://core.uidapi.com/client_side_keypairs/refresh", + "salts_metadata_path": "https://core.uidapi.com/salt/refresh", + "services_metadata_path": "https://core.uidapi.com/services/refresh", + "service_links_metadata_path": "https://core.uidapi.com/service_links/refresh", + "optout_metadata_path": "https://optout.uidapi.com/optout/refresh", + "core_attest_url": "https://core.uidapi.com/attest", + "optout_api_uri": "https://optout.uidapi.com/optout/replicate", "optout_s3_folder": "optout-v2/", "identity_token_expires_after_seconds": 259200 } diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index 8ae25914b..5731af324 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -8,6 +8,16 @@ if [ -z "${API_TOKEN_SECRET_NAME}" ]; then exit 1 fi +if [ -z "${CORE_BASE_URL}" ]; then + echo "CORE_BASE_URL cannot be empty" + exit 1 +fi + +if [ -z "${OPTOUT_BASE_URL}" ]; then + echo "OPTOUT_BASE_URL cannot be empty" + exit 1 +fi + export gcp_secret_version_name="${API_TOKEN_SECRET_NAME}" # -- locate config file @@ -34,14 +44,11 @@ if [ $? -ne 0 ]; then exit 1 fi -# -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently -if [ -n "${CORE_BASE_URL}" -a -n "${OPTOUT_BASE_URL}" -a "${DEPLOYMENT_ENVIRONMENT}" != 'prod' ]; then - echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" - sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} +echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}" +sed -i "s#https://core.uidapi.com#${CORE_BASE_URL}#g" ${FINAL_CONFIG} - sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} -fi +sed -i "s#https://optout.uidapi.com#${OPTOUT_BASE_URL}#g" ${FINAL_CONFIG} cat $FINAL_CONFIG diff --git a/scripts/gcp-oidc/terraform/main.tf b/scripts/gcp-oidc/terraform/main.tf index fedf09317..73fafc076 100644 --- a/scripts/gcp-oidc/terraform/main.tf +++ b/scripts/gcp-oidc/terraform/main.tf @@ -108,6 +108,8 @@ resource "google_compute_instance_template" "uid_operator" { tee-restart-policy = "Never" tee-env-DEPLOYMENT_ENVIRONMENT = var.uid_deployment_env tee-env-API_TOKEN_SECRET_NAME = module.secret-manager.secret_versions[0] + tee-env-CORE_BASE_URL = var.debug_mode ? "https://core-integ.uidapi.com" : "https://core-prod.uidapi.com" + tee-env-OPTOUT_BASE_URL = var.debug_mode ? "https://optout-integ.uidapi.com" : "https://optout-prod.uidapi.com" } network_interface { From 4a0b9e2100daafb1bf5ed86dac03e404f8f262c4 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 13:40:38 +0800 Subject: [PATCH 0105/1116] Added AWS Nitro enclave build pipeline --- .../publish-aws-nitro-enclave-docker.yaml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/publish-aws-nitro-enclave-docker.yaml diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml new file mode 100644 index 000000000..6498cc060 --- /dev/null +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -0,0 +1,46 @@ +name: Publish AWS Nitro Operator +run-name: ${{ format('Publish {0} AWS Nitro Operator', inputs.release_type) }} +on: + workflow_dispatch: + inputs: + release_type: + type: choice + description: 'The type of release' + options: + - Major + - Minor + - Patch + - Snapshot + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + type: string + default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false + workflow_call: + inputs: + release_type: + description: The type of version number to return. Must be one of [Snapshot, Patch, Minor or Major] + required: true + type: string + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + type: string + default: '' + skip_e2e_test: + description: If true, will skip the step for E2E tests + type: boolean + default: false + +jobs: + buildImage: + name: Build Image + runs-on: ubuntu-latest + steps: + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + with: + release_type: ${{ inputs.release_type }} From 8b5c7c4398c974b0e15dfebe52227a7705525a50 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:17:52 +0800 Subject: [PATCH 0106/1116] Commented out commit steps for testing --- .../publish-aws-nitro-enclave-docker.yaml | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 6e26929fb..529cb8f41 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -114,24 +114,24 @@ jobs: echo "Version number updated from $current_version to $new_version" echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT - - name: Commit pom.xml and version.json - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} - uses: EndBug/add-and-commit@v9 - with: - add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com - message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - - - name: Commit pom.xml, version.json and set tag - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} - uses: EndBug/add-and-commit@v9 - with: - add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com - message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} +# - name: Commit pom.xml and version.json +# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} +# uses: EndBug/add-and-commit@v9 +# with: +# add: 'pom.xml version.json' +# author_name: Release Workflow +# author_email: unifiedid-admin+release@thetradedesk.com +# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' +# +# - name: Commit pom.xml, version.json and set tag +# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} +# uses: EndBug/add-and-commit@v9 +# with: +# add: 'pom.xml version.json' +# author_name: Release Workflow +# author_email: unifiedid-admin+release@thetradedesk.com +# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' +# tag: v${{ steps.version.outputs.new_version }} - name: Run amazonlinux Docker image run: | From aaf21a0d905ab7f733d2228b9597edb38143c06e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:21:39 +0800 Subject: [PATCH 0107/1116] Removed AWS identity setup --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 529cb8f41..10aba296f 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -86,14 +86,6 @@ jobs: # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. fetch-depth: 0 - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: us-east-2 - role-to-assume: arn:aws:iam::072245134533:role/github-runner-for-uid2-operator - - run: aws sts get-caller-identity - shell: bash - - name: Restore timestamps uses: thetradedesk/git-restore-mtime-action@v1.2 From 3302ca7e34fb10a9bc79fcd60c9158ef38838bc9 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:22:50 +0800 Subject: [PATCH 0108/1116] Removed skip e2e test input param --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 10aba296f..577865257 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -15,10 +15,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false workflow_call: inputs: release_type: @@ -29,10 +25,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false outputs: pcr0: From 80c55dc00fab1c75792e2d10d79ea75afaf9c2a6 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:23:52 +0800 Subject: [PATCH 0109/1116] Commented check release type for testing --- .../workflows/publish-aws-nitro-enclave-docker.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 577865257..76e83b01e 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -42,11 +42,11 @@ jobs: outputs: pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: - - name: Check branch and release type - id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 - with: - release_type: ${{ inputs.release_type }} +# - name: Check branch and release type +# id: checkRelease +# uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 +# with: +# release_type: ${{ inputs.release_type }} - name: Show Context run: | @@ -55,7 +55,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} - IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} +# IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - name: Set up JDK uses: actions/setup-java@v3 From 1e48943e33472f308c8e795c3f259ceec84060b0 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:31:17 +0800 Subject: [PATCH 0110/1116] Fixed incorrect path --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- scripts/aws/pipeline/amazonlinux.Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 76e83b01e..41756efd9 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -65,14 +65,14 @@ jobs: - name: Checkout full history on Main uses: actions/checkout@v4 - if: ${{ inputs.version_number_input == ''}} + if: ${{ inputs.version_number_input == '' }} with: # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. fetch-depth: 0 - name: Checkout full history at tag v${{ inputs.version_number_input }} uses: actions/checkout@v4 - if: ${{ inputs.version_number_input != ''}} + if: ${{ inputs.version_number_input != '' }} with: ref: v${{ inputs.version_number_input }} # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. diff --git a/scripts/aws/pipeline/amazonlinux.Dockerfile b/scripts/aws/pipeline/amazonlinux.Dockerfile index a09ab1843..5573cb147 100644 --- a/scripts/aws/pipeline/amazonlinux.Dockerfile +++ b/scripts/aws/pipeline/amazonlinux.Dockerfile @@ -22,6 +22,6 @@ RUN yum -y install aws-nitro-enclaves-cli-devel RUN systemctl enable docker -COPY ./aws/pipeline/aws_nitro_eif.sh /aws_nitro_eif.sh +COPY ./scripts/aws/pipeline/aws_nitro_eif.sh /aws_nitro_eif.sh CMD ["/usr/sbin/init"] From 8994be222103559e14c09541baaf73fd5897bfe5 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:39:30 +0800 Subject: [PATCH 0111/1116] Removed JDK setup --- .github/actions/build_aws_ami/action.yaml | 32 +++++++++++++++++++ .../publish-aws-nitro-enclave-docker.yaml | 6 ---- 2 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 .github/actions/build_aws_ami/action.yaml diff --git a/.github/actions/build_aws_ami/action.yaml b/.github/actions/build_aws_ami/action.yaml new file mode 100644 index 000000000..c1c016c30 --- /dev/null +++ b/.github/actions/build_aws_ami/action.yaml @@ -0,0 +1,32 @@ +name: Build AWS AMI +description: Builds the AMI for AWS private operators + +inputs: + identity_scope: + description: The identity scope [uid2, euid] + required: true + +runs: + using: "composite" + + steps: + - name: Build EIF + id: buildEIF + shell: bash + run: | + make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif + docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ./build/${{ inputs.identity_scope }}operator.eif + + - name: Show PCR0 + id: showPCR0 + shell: bash + run: | + PCR0=$(nitro-cli describe-eif --eif-path ${{ inputs.identity_scope }}operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) + echo "PCR0: " $PCR0 + echo "PCR0=$PCR0" >> $GITHUB_OUTPUT + + - name: Set identity scope + id: setIdentityScope + shell: bash + run: | + echo "${${{ inputs.identity_scope}}@u}" >> ./build/identity_scope diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 41756efd9..15e5b5a4b 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -57,12 +57,6 @@ jobs: GITHUB_CONTEXT: ${{ toJson(github) }} # IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - - name: Set up JDK - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: '11' - - name: Checkout full history on Main uses: actions/checkout@v4 if: ${{ inputs.version_number_input == '' }} From 3c523682f8d993cbabc29b84f6cfc250441d98c9 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 14:53:36 +0800 Subject: [PATCH 0112/1116] Added CI space cleanup --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 15e5b5a4b..c2f6403bd 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -48,6 +48,10 @@ jobs: # with: # release_type: ${{ inputs.release_type }} + - name: Free up space + run: | + rm -rf /opt/hostedtoolcache + - name: Show Context run: | printenv From 0819905396c123e6671bdbfd44ec9ce61a9b9e92 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 15:17:12 +0800 Subject: [PATCH 0113/1116] Moved AWS EIF steps to action file --- .github/actions/build_aws_ami/action.yaml | 32 ------------ .github/actions/build_aws_eif/action.yaml | 52 +++++++++++++++++++ .../publish-aws-nitro-enclave-docker.yaml | 41 ++++----------- 3 files changed, 62 insertions(+), 63 deletions(-) delete mode 100644 .github/actions/build_aws_ami/action.yaml create mode 100644 .github/actions/build_aws_eif/action.yaml diff --git a/.github/actions/build_aws_ami/action.yaml b/.github/actions/build_aws_ami/action.yaml deleted file mode 100644 index c1c016c30..000000000 --- a/.github/actions/build_aws_ami/action.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: Build AWS AMI -description: Builds the AMI for AWS private operators - -inputs: - identity_scope: - description: The identity scope [uid2, euid] - required: true - -runs: - using: "composite" - - steps: - - name: Build EIF - id: buildEIF - shell: bash - run: | - make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif - docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ./build/${{ inputs.identity_scope }}operator.eif - - - name: Show PCR0 - id: showPCR0 - shell: bash - run: | - PCR0=$(nitro-cli describe-eif --eif-path ${{ inputs.identity_scope }}operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) - echo "PCR0: " $PCR0 - echo "PCR0=$PCR0" >> $GITHUB_OUTPUT - - - name: Set identity scope - id: setIdentityScope - shell: bash - run: | - echo "${${{ inputs.identity_scope}}@u}" >> ./build/identity_scope diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml new file mode 100644 index 000000000..434e64430 --- /dev/null +++ b/.github/actions/build_aws_eif/action.yaml @@ -0,0 +1,52 @@ +name: Build AWS EIF +description: Builds the EIF for AWS private operators + +inputs: + identity_scope: + description: The identity scope [uid2, euid] + required: true + artifacts_base_output_dir: + description: The base output directory for the AMI artifacts + required: true + +runs: + using: "composite" + + steps: + - name: Set identity scope + id: identityScope + shell: bash + run: | + echo "${${{ inputs.identity_scope }}@u}" >> ./build/identity_scope + + - name: Build EIF + id: EIF + shell: bash + run: | + make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif + docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ./build/${{ inputs.identity_scope }}operator.eif + + - name: Show PCR0 + id: PCR0 + shell: bash + run: | + PCR0=$(nitro-cli describe-eif --eif-path ${{ inputs.identity_scope }}operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) + echo "PCR0: ${PCR0}" + echo "PCR0=${PCR0}" >> ${GITHUB_OUTPUT} + + - name: Prepare artifacts + id: artifacts + shell: bash + run: | + ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" + mkdir -p ${ARTIFACTS_OUTPUT_DIR} + cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/identity_scope ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/pipeline/VERSION ${ARTIFACTS_OUTPUT_DIR}/ + cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index c2f6403bd..ad363bf1e 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,23 +115,6 @@ jobs: # message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' # tag: v${{ steps.version.outputs.new_version }} - - name: Run amazonlinux Docker image - run: | - docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . - docker run -d --privileged --name amazonlinux amazonlinux:latest - - - name: Build AWS Nitro EIF - run: | - make -f Makefile.nitro uid2operator.eif - docker cp amazonlinux:/uid2operator.eif ./build/uid2operator.eif - - - name: Show PCR0 - id: showPCR0 - run: | - PCR0=$(nitro-cli describe-eif --eif-path uid2operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) - echo "PCR0: " $PCR0 - echo "PCR0=$PCR0" >> $GITHUB_OUTPUT - - name: Download dante run: | wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz @@ -153,22 +136,18 @@ jobs: cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo make - - name: Prepare artifacts + - name: Run amazonlinux Docker image run: | - mkdir -p ${{ env.ARTIFACTS_OUTPUT_DIR }} - cp ./dante-1.4.3/sockd/sockd ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./build/uid2operator.eif ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./scripts/aws/start.sh ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./scripts/aws/stop.sh ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./scripts/aws/proxies.host.yaml ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./scripts/aws/sockd.conf ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./scripts/aws/uid2operator.service ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./scripts/aws/pipeline/VERSION ${{ env.ARTIFACTS_OUTPUT_DIR }}/ - cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${{ env.ARTIFACTS_OUTPUT_DIR }}/vsockpx - echo "UID2" >> ${{ env.ARTIFACTS_OUTPUT_DIR }}/identity_scope + docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . + docker run -d --privileged --name amazonlinux amazonlinux:latest + + - name: Build AWS EIF + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif + with: + identity_scope: uid2 + artifacts_base_output_dir: ${{ env.ARTIFACTS_OUTPUT_DIR }} - uses: actions/upload-artifact@v3 with: name: aws-nitro-deployment-files - path: | - ${{ env.ARTIFACTS_OUTPUT_DIR }} + path: ${{ env.ARTIFACTS_OUTPUT_DIR }} From 5d243d8c4e564ac17c6cf7931c8b51d0d9fbea26 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 15:57:47 +0800 Subject: [PATCH 0114/1116] Fixed identity scope casing --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 434e64430..ca6de51b5 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -17,7 +17,7 @@ runs: id: identityScope shell: bash run: | - echo "${${{ inputs.identity_scope }}@u}" >> ./build/identity_scope + echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' >> ./build/identity_scope - name: Build EIF id: EIF From fdf9bb3ff4d799ef8b045e6d3fd983a00cd13240 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 16:03:20 +0800 Subject: [PATCH 0115/1116] Added build folder creation --- .github/actions/build_aws_eif/action.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index ca6de51b5..c111b4859 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -13,21 +13,23 @@ runs: using: "composite" steps: + - name: Create build folder + shell: bash + run: | + mkdir -p build/ + - name: Set identity scope - id: identityScope shell: bash run: | echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' >> ./build/identity_scope - name: Build EIF - id: EIF shell: bash run: | make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ./build/${{ inputs.identity_scope }}operator.eif - name: Show PCR0 - id: PCR0 shell: bash run: | PCR0=$(nitro-cli describe-eif --eif-path ${{ inputs.identity_scope }}operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) @@ -35,7 +37,6 @@ runs: echo "PCR0=${PCR0}" >> ${GITHUB_OUTPUT} - name: Prepare artifacts - id: artifacts shell: bash run: | ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" From 0344655c60aa7c56cb216a50bb2c35edb2915984 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 16:26:39 +0800 Subject: [PATCH 0116/1116] Added EUID step and PCR0 output --- .github/actions/build_aws_eif/action.yaml | 5 ++--- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 8 +++++++- scripts/aws/pipeline/aws_nitro_eif.sh | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index c111b4859..ba49970b7 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -32,9 +32,8 @@ runs: - name: Show PCR0 shell: bash run: | - PCR0=$(nitro-cli describe-eif --eif-path ${{ inputs.identity_scope }}operator.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) - echo "PCR0: ${PCR0}" - echo "PCR0=${PCR0}" >> ${GITHUB_OUTPUT} + docker cp amazonlinux:/pcr0.txt ./build/pcr0.txt + cat pcr0.txt - name: Prepare artifacts shell: bash diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ad363bf1e..d613f5565 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -141,12 +141,18 @@ jobs: docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . docker run -d --privileged --name amazonlinux amazonlinux:latest - - name: Build AWS EIF + - name: Build UID2 AWS EIF uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_OUTPUT_DIR }} + - name: Build EUID AWS EIF + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif + with: + identity_scope: euid + artifacts_base_output_dir: ${{ env.ARTIFACTS_OUTPUT_DIR }} + - uses: actions/upload-artifact@v3 with: name: aws-nitro-deployment-files diff --git a/scripts/aws/pipeline/aws_nitro_eif.sh b/scripts/aws/pipeline/aws_nitro_eif.sh index 7a7aacaa2..8aa75f860 100644 --- a/scripts/aws/pipeline/aws_nitro_eif.sh +++ b/scripts/aws/pipeline/aws_nitro_eif.sh @@ -11,3 +11,6 @@ done docker load -i /$1.tar nitro-cli build-enclave --docker-uri $1 --output-file $1.eif + +PCR0=$(nitro-cli describe-eif --eif-path $1.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) +echo "PCR0=${PCR0}" >> pcr0.txt From 14bfcd803d4020b476ed875fef269a6935d987b9 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 17:36:10 +0800 Subject: [PATCH 0117/1116] Added vim-common in amazonlinux Docker image --- scripts/aws/pipeline/amazonlinux.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/pipeline/amazonlinux.Dockerfile b/scripts/aws/pipeline/amazonlinux.Dockerfile index 5573cb147..d4372c3ee 100644 --- a/scripts/aws/pipeline/amazonlinux.Dockerfile +++ b/scripts/aws/pipeline/amazonlinux.Dockerfile @@ -4,7 +4,7 @@ FROM amazonlinux:2 RUN yum -y update # systemd is not a hard requirement for Amazon ECS Anywhere, but the installation script currently only supports systemd to run. # Amazon ECS Anywhere can be used without systemd, if you set up your nodes and register them into your ECS cluster **without** the installation script. -RUN yum -y install systemd +RUN yum -y install systemd vim-common RUN yum clean all RUN cd /lib/systemd/system/sysinit.target.wants/; \ From 33d6f9d056ca1bd7cc7d03045acc6675eda83c1d Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 17:47:53 +0800 Subject: [PATCH 0118/1116] Updated PCR0 txt filepath --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index ba49970b7..e7d866929 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -33,7 +33,7 @@ runs: shell: bash run: | docker cp amazonlinux:/pcr0.txt ./build/pcr0.txt - cat pcr0.txt + cat ./build/pcr0.txt - name: Prepare artifacts shell: bash From 1360e89718dc78b4bebf6a6f76a986e839402481 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 20 Feb 2024 18:08:28 +0800 Subject: [PATCH 0119/1116] Uncommented version commit --- .../publish-aws-nitro-enclave-docker.yaml | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index d613f5565..3cf8da5d2 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -42,11 +42,11 @@ jobs: outputs: pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: -# - name: Check branch and release type -# id: checkRelease -# uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 -# with: -# release_type: ${{ inputs.release_type }} + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + with: + release_type: ${{ inputs.release_type }} - name: Free up space run: | @@ -59,7 +59,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} -# IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - name: Checkout full history on Main uses: actions/checkout@v4 @@ -96,24 +96,24 @@ jobs: echo "Version number updated from $current_version to $new_version" echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT -# - name: Commit pom.xml and version.json -# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} -# uses: EndBug/add-and-commit@v9 -# with: -# add: 'pom.xml version.json' -# author_name: Release Workflow -# author_email: unifiedid-admin+release@thetradedesk.com -# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' -# -# - name: Commit pom.xml, version.json and set tag -# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} -# uses: EndBug/add-and-commit@v9 -# with: -# add: 'pom.xml version.json' -# author_name: Release Workflow -# author_email: unifiedid-admin+release@thetradedesk.com -# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' -# tag: v${{ steps.version.outputs.new_version }} + - name: Commit pom.xml and version.json + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + + - name: Commit pom.xml, version.json and set tag + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + tag: v${{ steps.version.outputs.new_version }} - name: Download dante run: | From c14bbfb6c8123059e657fc5139015a793a774e1b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 21 Feb 2024 12:58:41 +1100 Subject: [PATCH 0120/1116] Updating version of Shared --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index baab7c48a..c94de034e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.0-d4082509df + 5.27.1-SNAPSHOT UTF-8 @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.0.0-b264db84a3 + 7.1.0-8e67b3a537 ${project.version} From c25692a2165abd96e1d5276202092e35ecf85b8b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 21 Feb 2024 13:56:53 +1100 Subject: [PATCH 0121/1116] Removed unused includes --- .../uid2/operator/nitro/AttestationTest.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/test/java/com/uid2/operator/nitro/AttestationTest.java b/src/test/java/com/uid2/operator/nitro/AttestationTest.java index 0b905bb16..3c99569fd 100644 --- a/src/test/java/com/uid2/operator/nitro/AttestationTest.java +++ b/src/test/java/com/uid2/operator/nitro/AttestationTest.java @@ -1,25 +1,5 @@ package com.uid2.operator.nitro; -import com.uid2.shared.Const; -import com.uid2.shared.attest.AttestationFactory; -import com.uid2.shared.secure.AttestationResult; -import com.uid2.shared.secure.NitroAttestationProvider; -import com.uid2.shared.secure.NitroEnclaveIdentifier; -import com.uid2.shared.secure.nitro.AttestationRequest; -import com.uid2.shared.secure.nitro.InMemoryAWSCertificateStore; -import org.junit.Test; - -import javax.crypto.Cipher; - -import static org.junit.Assert.*; - -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.spec.KeySpec; -import java.security.spec.RSAPublicKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; - public class AttestationTest { // @Test From c034c11b8c618173b00e8d96493403efa9ef99c5 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 21 Feb 2024 13:21:13 +0800 Subject: [PATCH 0122/1116] Added version number to build artifacts --- .github/actions/build_aws_eif/action.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index e7d866929..7b27405b7 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -21,7 +21,14 @@ runs: - name: Set identity scope shell: bash run: | - echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' >> ./build/identity_scope + echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' >> ./build/identity_scope.txt + cat ./build/identity_scope.txt + + - name: Get version number from pom.xml + shell: bash + run: | + echo `grep -o '.*' ./pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/'` >> ./build/version_number.txt + cat ./build/version_number.txt - name: Build EIF shell: bash @@ -42,7 +49,9 @@ runs: mkdir -p ${ARTIFACTS_OUTPUT_DIR} cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ cp ./build/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/identity_scope ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/version_number.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ From ef1b767308f91790e1da1ee7c5eec7943b6db767 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 21 Feb 2024 13:48:38 +0800 Subject: [PATCH 0123/1116] Updated identity_scope filename --- scripts/aws/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/start.sh b/scripts/aws/start.sh index 756b902ba..705acb80b 100644 --- a/scripts/aws/start.sh +++ b/scripts/aws/start.sh @@ -2,7 +2,7 @@ echo "$HOSTNAME" > /etc/uid2operator/HOSTNAME EIF_PATH=${EIF_PATH:-/opt/uid2operator/uid2operator.eif} -IDENTITY_SCOPE=${IDENTITY_SCOPE:-$(cat /opt/uid2operator/identity_scope)} +IDENTITY_SCOPE=${IDENTITY_SCOPE:-$(cat /opt/uid2operator/identity_scope.txt)} CID=${CID:-42} AWS_REGION_NAME=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r '.region') if [ "$IDENTITY_SCOPE" = 'UID2' ]; then From 171fbf9417d32df4febff3db3c23e883aaeb32e9 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 21 Feb 2024 13:49:41 +0800 Subject: [PATCH 0124/1116] Reformatted files --- scripts/aws/Dockerfile | 26 ++++++++++++++------------ scripts/aws/install.sh | 10 +++++++--- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 36ed33f0e..211c68877 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -1,10 +1,12 @@ FROM openjdk:11.0-jre-slim-bullseye WORKDIR /app + ARG JAR_NAME=uid2-operator ARG JAR_VERSION=1.0.0 ARG IMAGE_VERSION=1.0.0.unknownhash ARG IDENTITY_SCOPE=UID2 + ENV JAR_NAME=${JAR_NAME} ENV JAR_VERSION=${JAR_VERSION} ENV IMAGE_VERSION=${IMAGE_VERSION} @@ -18,19 +20,19 @@ RUN apt update -y \ RUN pip3 install boto3==1.16.9 COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar -COPY ./static /app/static -COPY ./vsockpx /app/ -COPY ./libjnsm.so /app/lib/ -COPY ./load_config.py /app/ -COPY ./make_config.py /app/ -COPY ./entrypoint.sh /app/ +COPY ./static /app/static +COPY ./libjnsm.so /app/lib/ +COPY ./vsockpx /app/ +COPY ./load_config.py /app/ +COPY ./make_config.py /app/ +COPY ./entrypoint.sh /app/ COPY ./proxies.nitro.yaml /app/ -COPY ./conf/default-config.json /app/conf/ -COPY conf/prod-uid2-config.json /app/conf/prod-uid2-config.json -COPY conf/integ-uid2-config.json /app/conf/integ-uid2-config.json -COPY ./conf/prod-euid-config.json /app/conf/prod-euid-config.json -COPY ./conf/integ-euid-config.json /app/conf/integ-euid-config.json -COPY ./conf/*.xml /app/conf/ +COPY ./conf/default-config.json /app/conf/ +COPY ./conf/prod-uid2-config.json /app/conf/ +COPY ./conf/integ-uid2-config.json /app/conf/ +COPY ./conf/prod-euid-config.json /app/conf/ +COPY ./conf/integ-euid-config.json /app/conf/ +COPY ./conf/*.xml /app/conf/ RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh diff --git a/scripts/aws/install.sh b/scripts/aws/install.sh index f04fa7d57..2ab72706e 100644 --- a/scripts/aws/install.sh +++ b/scripts/aws/install.sh @@ -4,11 +4,15 @@ PROJECT_DIR=${PROJECT_DIR:-.} mkdir -p /etc/uid2operator mkdir -p /opt/uid2operator + cp $PROJECT_DIR/dependencies/vsockpx /usr/bin/ chmod +x /usr/bin/vsockpx -cp $PROJECT_DIR/proxies.host.yaml /etc/uid2operator/proxy.yaml + +cp $PROJECT_DIR/proxies.host.yaml /etc/uid2operator/proxy.yaml cp $PROJECT_DIR/allocator.template.yaml /etc/uid2operator/ + cp $PROJECT_DIR/uid2operator.eif /opt/uid2operator/ -cp $PROJECT_DIR/start.sh /opt/uid2operator/ -cp $PROJECT_DIR/stop.sh /opt/uid2operator/ +cp $PROJECT_DIR/start.sh /opt/uid2operator/ +cp $PROJECT_DIR/stop.sh /opt/uid2operator/ + cp $PROJECT_DIR/uid2operator.service /etc/systemd/system/ \ No newline at end of file From ba13a5cab1600cc1b42237fe414f4a014e4d8462 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 21 Feb 2024 13:52:13 +0800 Subject: [PATCH 0125/1116] Reenabled comments for test --- .../publish-aws-nitro-enclave-docker.yaml | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 3cf8da5d2..d613f5565 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -42,11 +42,11 @@ jobs: outputs: pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: - - name: Check branch and release type - id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 - with: - release_type: ${{ inputs.release_type }} +# - name: Check branch and release type +# id: checkRelease +# uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 +# with: +# release_type: ${{ inputs.release_type }} - name: Free up space run: | @@ -59,7 +59,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} - IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} +# IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - name: Checkout full history on Main uses: actions/checkout@v4 @@ -96,24 +96,24 @@ jobs: echo "Version number updated from $current_version to $new_version" echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT - - name: Commit pom.xml and version.json - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} - uses: EndBug/add-and-commit@v9 - with: - add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com - message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - - - name: Commit pom.xml, version.json and set tag - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} - uses: EndBug/add-and-commit@v9 - with: - add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com - message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} +# - name: Commit pom.xml and version.json +# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} +# uses: EndBug/add-and-commit@v9 +# with: +# add: 'pom.xml version.json' +# author_name: Release Workflow +# author_email: unifiedid-admin+release@thetradedesk.com +# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' +# +# - name: Commit pom.xml, version.json and set tag +# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} +# uses: EndBug/add-and-commit@v9 +# with: +# add: 'pom.xml version.json' +# author_name: Release Workflow +# author_email: unifiedid-admin+release@thetradedesk.com +# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' +# tag: v${{ steps.version.outputs.new_version }} - name: Download dante run: | From 724835cd780dfdf48dc86462b731d169841422d6 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 21 Feb 2024 14:32:49 +0800 Subject: [PATCH 0126/1116] Added EUID_VERSION file --- .github/actions/build_aws_eif/action.yaml | 22 +++++++++---------- scripts/aws/pipeline/EUID_VERSION | 1 + .../aws/pipeline/{VERSION => UID2_VERSION} | 0 3 files changed, 12 insertions(+), 11 deletions(-) create mode 100644 scripts/aws/pipeline/EUID_VERSION rename scripts/aws/pipeline/{VERSION => UID2_VERSION} (100%) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 7b27405b7..2290a5449 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -47,15 +47,15 @@ runs: run: | ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" mkdir -p ${ARTIFACTS_OUTPUT_DIR} - cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/version_number.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/pipeline/VERSION ${ARTIFACTS_OUTPUT_DIR}/ + cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/version_number.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ./build/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/pipeline/$(cat ./build/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/ cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx diff --git a/scripts/aws/pipeline/EUID_VERSION b/scripts/aws/pipeline/EUID_VERSION new file mode 100644 index 000000000..b1bd38b62 --- /dev/null +++ b/scripts/aws/pipeline/EUID_VERSION @@ -0,0 +1 @@ +13 diff --git a/scripts/aws/pipeline/VERSION b/scripts/aws/pipeline/UID2_VERSION similarity index 100% rename from scripts/aws/pipeline/VERSION rename to scripts/aws/pipeline/UID2_VERSION From 5cccae595c0a89318d5e7d68a52102a1b37c5411 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 21 Feb 2024 14:50:02 +0800 Subject: [PATCH 0127/1116] Fixed build file structure --- .github/actions/build_aws_eif/action.yaml | 43 ++++++++++++----------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 2290a5449..1d931c185 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -14,48 +14,51 @@ runs: steps: - name: Create build folder + id: buildFolder shell: bash run: | - mkdir -p build/ + BUILD_FOLDER="./build/${{ inputs.identity_scope }}" + mkdir -p $BUILD_FOLDER + echo "BUILD_FOLDER=$BUILD_FOLDER" >> $GITHUB_OUTPUT - name: Set identity scope shell: bash run: | - echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' >> ./build/identity_scope.txt - cat ./build/identity_scope.txt + echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' > ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt + cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt - name: Get version number from pom.xml shell: bash run: | - echo `grep -o '.*' ./pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/'` >> ./build/version_number.txt - cat ./build/version_number.txt + echo `grep -o '.*' ./pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/'` > ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt + cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt - name: Build EIF shell: bash run: | make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif - docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ./build/${{ inputs.identity_scope }}operator.eif + docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/${{ inputs.identity_scope }}operator.eif - name: Show PCR0 shell: bash run: | - docker cp amazonlinux:/pcr0.txt ./build/pcr0.txt - cat ./build/pcr0.txt + docker cp amazonlinux:/pcr0.txt ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/pcr0.txt + cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/pcr0.txt - name: Prepare artifacts shell: bash run: | ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" mkdir -p ${ARTIFACTS_OUTPUT_DIR} - cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/version_number.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ./build/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/pipeline/$(cat ./build/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/ - cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx + cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ + cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/ + cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx From 9907484eec9b3dd931f5715de1e01ab36353fc51 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 22 Feb 2024 03:06:16 +0000 Subject: [PATCH 0128/1116] Released Patch version: 5.27.6-396bb357e3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c94de034e..02a6982a0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.1-SNAPSHOT + 5.27.6-396bb357e3 UTF-8 From e06b255b4de813a9e7dd4047aacbd3cd67609bba Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 22 Feb 2024 14:25:45 +0800 Subject: [PATCH 0129/1116] Moved dante/vsock proxy builds to Docker build --- .github/actions/build_aws_eif/action.yaml | 21 +++---- .../publish-aws-nitro-enclave-docker.yaml | 21 ------- Makefile.nitro | 56 ++++++++++++++----- scripts/aws/pipeline/aws_nitro_eif.sh | 3 +- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 1d931c185..59bac1143 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -21,7 +21,7 @@ runs: mkdir -p $BUILD_FOLDER echo "BUILD_FOLDER=$BUILD_FOLDER" >> $GITHUB_OUTPUT - - name: Set identity scope + - name: Get identity scope shell: bash run: | echo "${{ inputs.identity_scope }}" | tr '[:lower:]' '[:upper:]' > ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt @@ -30,35 +30,30 @@ runs: - name: Get version number from pom.xml shell: bash run: | - echo `grep -o '.*' ./pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/'` > ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt + grep -o '.*' ./pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/' > ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt - name: Build EIF shell: bash run: | make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif - docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/${{ inputs.identity_scope }}operator.eif - - - name: Show PCR0 - shell: bash - run: | - docker cp amazonlinux:/pcr0.txt ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/pcr0.txt - cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/pcr0.txt - name: Prepare artifacts shell: bash run: | ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" mkdir -p ${ARTIFACTS_OUTPUT_DIR} - cp ./dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ - cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/version_number.txt ${ARTIFACTS_OUTPUT_DIR}/ - cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/start.sh ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/stop.sh ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/ - cp ./uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx + + docker cp amazonlinux:/build/uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx + docker cp amazonlinux:/build/dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index d613f5565..864a613c4 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,27 +115,6 @@ jobs: # message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' # tag: v${{ steps.version.outputs.new_version }} - - name: Download dante - run: | - wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz - echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum - sha256sum --check dante_checksum - tar -xf dante-1.4.3.tar.gz - - - name: Make dante - working-directory: ./dante-1.4.3 - run: | - ./configure - make - - - name: Make vsockpx for Amazon Linux 2 - run: | - git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git - mkdir uid2-aws-enclave-vsockproxy/build - cd uid2-aws-enclave-vsockproxy/build - cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo - make - - name: Run amazonlinux Docker image run: | docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . diff --git a/Makefile.nitro b/Makefile.nitro index b4fabf42b..a2e36b8e0 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -4,18 +4,22 @@ DATA_DIR=/opt/uid2operator .PHONY: all all: build_eif -install: ./build/uid2operator.eif ./build/dante-1.4.3/sockd ./scripts/aws/start.sh ./scripts/aws/stop.sh ./scripts/aws/allocator.template.yaml ./scripts/aws/proxies.host.yaml ./scripts/aws/uid2operator.service ./build/vsockpx +################################################################################################################################################################## + +# Base + +install: ./build/uid2operator.eif ./build/dante-1.4.3/sockd ./build/uid2-aws-enclave-vsockproxy/build/vsock-bridge ./scripts/aws/start.sh ./scripts/aws/stop.sh ./scripts/aws/allocator.template.yaml ./scripts/aws/proxies.host.yaml ./scripts/aws/uid2operator.service mkdir -p $(CONFIG_DIR) mkdir -p $(DATA_DIR) - cp ./scripts/aws/proxies.host.yaml $(CONFIG_DIR)/proxy.yaml - cp ./scripts/aws/allocator.template.yaml $(CONFIG_DIR)/ - cp ./build/uid2operator.eif $(DATA_DIR)/ - cp ./scripts/aws/start.sh $(DATA_DIR)/start.sh - cp ./scripts/aws/stop.sh $(DATA_DIR)/stop.sh - cp ./scripts/aws/uid2operator.service /etc/systemd/system/ - cp ./build/vsockpx /usr/bin/ - cp ./scripts/aws/sockd.conf /etc/ - cp ./build/dante-1.4.3/sockd/sockd /usr/bin + cp ./scripts/aws/proxies.host.yaml $(CONFIG_DIR)/proxy.yaml + cp ./scripts/aws/allocator.template.yaml $(CONFIG_DIR)/ + cp ./build/uid2operator.eif $(DATA_DIR)/ + cp ./scripts/aws/start.sh $(DATA_DIR)/start.sh + cp ./scripts/aws/stop.sh $(DATA_DIR)/stop.sh + cp ./scripts/aws/sockd.conf /etc/ + cp ./scripts/aws/uid2operator.service /etc/systemd/system/ + cp ./build/uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge /usr/bin/vsockpx + cp ./build/dante-1.4.3/sockd/sockd /usr/bin/ chmod +x /usr/bin/vsockpx uninstall: @@ -27,12 +31,28 @@ uninstall: clean: rm -rf build +################################################################################################################################################################## + +# Dependencies + ./build/dante-1.4.3/sockd: - cd build; wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz - cd build; tar -xf dante-1.4.3.tar.gz + cd build; wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz + cd build; echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum + cd build; sha256sum --check dante_checksum + cd build; tar -xf dante-1.4.3.tar.gz cd build/dante-1.4.3; ./configure cd build/dante-1.4.3; make +./build/uid2-aws-enclave-vsockproxy/build/vsock-bridge: + cd build; git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git + cd build/uid2-aws-enclave-vsockproxy; mkdir -p build/ + cd build/uid2-aws-enclave-vsockproxy/build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo + cd build/uid2-aws-enclave-vsockproxy/build; make + +################################################################################################################################################################## + +# EIF + build_eif: uid2operator.eif euidoperator.eif euidoperator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py @@ -43,12 +63,20 @@ uid2operator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh b cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./uid2operator.tar uid2operator; docker cp ./uid2operator.tar amazonlinux:/uid2operator.tar docker exec amazonlinux bash aws_nitro_eif.sh uid2operator +################################################################################################################################################################## + +# Config scripts + build/load_config.py: ./scripts/aws/load_config.py cp ./scripts/aws/load_config.py ./build/ build/make_config.py: ./scripts/aws/make_config.py cp ./scripts/aws/make_config.py ./build/ +################################################################################################################################################################## + +# Artifacts + build/configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.loki.xml build/conf/default-config.json: build_artifacts ./scripts/aws/conf/default-config.json @@ -66,8 +94,8 @@ build/conf/integ-uid2-config.json: build_artifacts ./scripts/aws/conf/integ-uid2 build/conf/integ-euid-config.json: build_artifacts ./scripts/aws/conf/integ-euid-config.json cp ./scripts/aws/conf/integ-euid-config.json ./build/conf/integ-euid-config.json -build/conf/logback.loki.xml: ./scripts/aws/conf/logback.loki.xml - cp ./scripts/aws/conf/logback.loki.xml build/conf/logback.loki.xml +build/conf/logback.loki.xml: build_artifacts ./scripts/aws/conf/logback.loki.xml + cp ./scripts/aws/conf/logback.loki.xml ./build/conf/logback.loki.xml build/Dockerfile: build_artifacts ./scripts/aws/Dockerfile cp ./scripts/aws/Dockerfile ./build/ diff --git a/scripts/aws/pipeline/aws_nitro_eif.sh b/scripts/aws/pipeline/aws_nitro_eif.sh index 8aa75f860..e08380364 100644 --- a/scripts/aws/pipeline/aws_nitro_eif.sh +++ b/scripts/aws/pipeline/aws_nitro_eif.sh @@ -12,5 +12,4 @@ done docker load -i /$1.tar nitro-cli build-enclave --docker-uri $1 --output-file $1.eif -PCR0=$(nitro-cli describe-eif --eif-path $1.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64) -echo "PCR0=${PCR0}" >> pcr0.txt +nitro-cli describe-eif --eif-path $1.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64 > pcr0.txt From 855788eb17aa6523c2132f7535a927dbb093f62f Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Fri, 23 Feb 2024 11:31:08 +1100 Subject: [PATCH 0130/1116] UID2-2799 Revert entrypoint change for overriding core and optout base url (#359) * Test on custom branch * Remove `enforce_https` override * Update shared to `7.1.11-SNAPSHOT` * Use v2 shared action * Use custom branch * Bump pom.xml shared version * Remove unnecessary change * Use v2 of shared-action * Update shared to `7.1.13-SNAPSHOT` * Update shared version to `7.2.0-41efc58fbf` --- pom.xml | 2 +- scripts/azure-cc/conf/integ-uid2-config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 02a6982a0..94de38804 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.1.0-8e67b3a537 + 7.2.0-41efc58fbf ${project.version} diff --git a/scripts/azure-cc/conf/integ-uid2-config.json b/scripts/azure-cc/conf/integ-uid2-config.json index ac8263034..2cd4be5c3 100644 --- a/scripts/azure-cc/conf/integ-uid2-config.json +++ b/scripts/azure-cc/conf/integ-uid2-config.json @@ -10,5 +10,5 @@ "optout_metadata_path": "https://optout-integ.uidapi.com/optout/refresh", "core_attest_url": "https://core-integ.uidapi.com/attest", "optout_api_uri": "https://optout-integ.uidapi.com/optout/replicate", - "optout_s3_folder": "uid-optout-integ/", + "optout_s3_folder": "uid-optout-integ/" } From 92398fcce1b3a3f769f52937e9672d4d9d65f8e7 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Fri, 23 Feb 2024 11:41:27 +1100 Subject: [PATCH 0131/1116] UID2-2772 Enable e2e tests for azure and gcp (#360) * Test on custom branch * Remove `enforce_https` override * Use v2 shared action * Use custom branch * Remove unnecessary change * Use v2 of shared-action * Enable e2e tests for azure and gcp * Use kcc-UID2-2772-enable-e2e-tests branch * Remove e2e folder from operator * Revert kcc-UID2-2772-enable-e2e-tests to v2 --- .../publish-azure-cc-enclave-docker.yaml | 9 - .../publish-gcp-oidc-enclave-docker.yaml | 9 - e2e/.gitignore | 1 - e2e/README.md | 33 ---- e2e/azure/parameters.json | 30 ---- e2e/azure/template.json | 159 ------------------ e2e/docker/localstack/init-aws.sh | 7 - e2e/docker/localstack/kms/seed.yaml | 36 ---- e2e/e2e.sh | 56 ------ e2e/healthcheck.sh | 26 --- e2e/jq_helper.sh | 21 --- e2e/ngrok.yml | 12 -- e2e/prepare_azure_cc_artifacts.sh | 66 -------- e2e/prepare_azure_cc_enclave_metadata.sh | 33 ---- e2e/prepare_conf.sh | 19 --- e2e/prepare_gcp_enclave_metadata.sh | 33 ---- e2e/setup_ngrok.sh | 51 ------ e2e/start_azure_cc_enclave.sh | 91 ---------- e2e/start_docker.sh | 66 -------- e2e/start_gcp_enclave.sh | 79 --------- e2e/stop_azure_cc_enclave.sh | 13 -- e2e/stop_gcp_enclave.sh | 27 --- 22 files changed, 877 deletions(-) delete mode 100644 e2e/.gitignore delete mode 100644 e2e/README.md delete mode 100644 e2e/azure/parameters.json delete mode 100644 e2e/azure/template.json delete mode 100755 e2e/docker/localstack/init-aws.sh delete mode 100644 e2e/docker/localstack/kms/seed.yaml delete mode 100644 e2e/e2e.sh delete mode 100644 e2e/healthcheck.sh delete mode 100644 e2e/jq_helper.sh delete mode 100644 e2e/ngrok.yml delete mode 100644 e2e/prepare_azure_cc_artifacts.sh delete mode 100644 e2e/prepare_azure_cc_enclave_metadata.sh delete mode 100644 e2e/prepare_conf.sh delete mode 100755 e2e/prepare_gcp_enclave_metadata.sh delete mode 100755 e2e/setup_ngrok.sh delete mode 100644 e2e/start_azure_cc_enclave.sh delete mode 100644 e2e/start_docker.sh delete mode 100644 e2e/start_gcp_enclave.sh delete mode 100644 e2e/stop_azure_cc_enclave.sh delete mode 100644 e2e/stop_gcp_enclave.sh diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 01a317a63..05d0f61e9 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -15,10 +15,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false workflow_call: inputs: release_type: @@ -29,10 +25,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false outputs: image_tag: @@ -253,7 +245,6 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test == 'false' }} needs: buildImage with: operator_type: azure diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 27591bb6d..5c9da76d2 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -15,10 +15,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false workflow_call: inputs: release_type: @@ -29,10 +25,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false outputs: image_tag: @@ -290,7 +282,6 @@ jobs: e2e: name: E2E uses: ./.github/workflows/run-e2e-tests-on-operator.yaml - if: ${{ inputs.skip_e2e_test == 'false' }} needs: buildImage with: operator_type: gcp diff --git a/e2e/.gitignore b/e2e/.gitignore deleted file mode 100644 index 15df91c4d..000000000 --- a/e2e/.gitignore +++ /dev/null @@ -1 +0,0 @@ -azure-artifacts diff --git a/e2e/README.md b/e2e/README.md deleted file mode 100644 index 6991b9c36..000000000 --- a/e2e/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -This folder provides some scripts to be used by github action to run GCP enclave E2E test. - -You could also leverage them to bring up a local docker-compose cluster contains: - - localstack (local S3) - - core (depends on localstack) - - optout (depends on localstack and core) - -and expose public Urls via ngrok, which could be used for private operator test. - -# How to run locally -Set below config in `./e2e/e2e.sh` - - NGROK_TOKEN: register a NGROK account and fetch from https://dashboard.ngrok.com/get-started/your-authtoken - - CORE_VERSION: the core image version - - OPTOUT_VERSION: the optout image version - - IMAGE_HASH: the image hash "sha256:..." for your operator image, this is to generate valid GCP OIDC enclave_id - - AZURE_CC_POLICY_DIGEST: Azure CC policy digest to be used as enclave_id - -and run below command under repo root: - -``` -bash ./e2e/e2e.sh -``` - -It will copy `e2e` folder to `e2e-target` folder and invoke from there. - -Other scripts that may help: - - `start_gcp_enclave.sh`: start a GCP enclave and run basic health check. - - `stop_gcp_enclave.sh`: stop a GCP enclave and delete the VM instance. - -Notes: -If you are running in mac, you may need to install `GNU sed` and `alias sed=gsed` \ No newline at end of file diff --git a/e2e/azure/parameters.json b/e2e/azure/parameters.json deleted file mode 100644 index 96add5d27..000000000 --- a/e2e/azure/parameters.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "containerGroupName": { - "value": "" - }, - "location": { - "value": "" - }, - "identity": { - "value": "" - }, - "vaultName": { - "value": "" - }, - "operatorKeySecretName": { - "value": "" - }, - "deploymentEnvironment": { - "value": "" - }, - "coreBaseUrl": { - "value": "" - }, - "optoutBaseUrl": { - "value": "" - } - } -} diff --git a/e2e/azure/template.json b/e2e/azure/template.json deleted file mode 100644 index e985d38d9..000000000 --- a/e2e/azure/template.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "containerGroupName": { - "type": "string", - "metadata": { - "description": "Name for the container group" - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for the container group" - } - }, - "identity": { - "type": "string", - "metadata": { - "description": "ManagedIdentity to launch the container" - } - }, - "vaultName": { - "type": "string", - "metadata": { - "description": "Vault name" - } - }, - "operatorKeySecretName": { - "type": "string", - "metadata": { - "description": "Operator key secret name" - } - }, - "deploymentEnvironment": { - "type": "string", - "metadata": { - "description": "Deployment environment" - } - }, - "coreBaseUrl": { - "type": "string", - "metadata": { - "description": "UID2 core base url override" - } - }, - "optoutBaseUrl": { - "type": "string", - "metadata": { - "description": "UID2 optout base url override" - } - } - }, - "resources": [ - { - "type": "Microsoft.ContainerInstance/containerGroups", - "apiVersion": "2023-05-01", - "name": "[parameters('containerGroupName')]", - "location": "[parameters('location')]", - "identity": { - "type": "userAssigned", - "userAssignedIdentities": { - "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('identity'))]": {} - } - }, - "properties": { - "confidentialComputeProperties": { - "ccePolicy": "" - }, - "containers": [ - { - "name": "skr", - "properties": { - "image": "mcr.microsoft.com/aci/skr:2.3", - "command": [ - "/skr.sh" - ], - "ports": [ - { - "port": 9000 - } - ], - "resources": { - "requests": { - "cpu": 1, - "memoryInGB": 1 - } - }, - "environmentVariables": [ - { - "name": "Port", - "value": "9000" - } - ] - } - }, - { - "name": "uid2-operator", - "properties": { - "image": "IMAGE_PLACEHOLDER", - "ports": [ - { - "port": 8080, - "protocol": "TCP" - } - ], - "resources": { - "requests": { - "cpu": 1, - "memoryInGB": 4 - } - }, - "environmentVariables": [ - { - "name": "VAULT_NAME", - "value": "[parameters('vaultName')]" - }, - { - "name": "OPERATOR_KEY_SECRET_NAME", - "value": "[parameters('operatorKeySecretName')]" - }, - { - "name": "DEPLOYMENT_ENVIRONMENT", - "value": "[parameters('deploymentEnvironment')]" - }, - { - "name": "CORE_BASE_URL", - "value": "[parameters('coreBaseUrl')]" - }, - { - "name": "OPTOUT_BASE_URL", - "value": "[parameters('optoutBaseUrl')]" - } - ] - } - } - ], - "sku": "Confidential", - "osType": "Linux", - "restartPolicy": "Never", - "ipAddress": { - "type": "Public", - "ports": [ - { - "port": "8080", - "protocol": "TCP" - } - ] - } - } - } - ], - "outputs": { - "containerIPv4Address": { - "type": "string", - "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups', parameters('containerGroupName'))).ipAddress.ip]" - } - } -} diff --git a/e2e/docker/localstack/init-aws.sh b/e2e/docker/localstack/init-aws.sh deleted file mode 100755 index 848a63983..000000000 --- a/e2e/docker/localstack/init-aws.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -aws s3 --endpoint-url http://localhost:5001 mb s3://test-core-bucket -aws s3 --endpoint-url http://localhost:5001 cp /s3/core/ s3://test-core-bucket/ --recursive - -aws s3 --endpoint-url http://localhost:5001 mb s3://test-optout-bucket -aws s3 --endpoint-url http://localhost:5001 cp /s3/optout/ s3://test-optout-bucket/ --recursive diff --git a/e2e/docker/localstack/kms/seed.yaml b/e2e/docker/localstack/kms/seed.yaml deleted file mode 100644 index 8fe65fe41..000000000 --- a/e2e/docker/localstack/kms/seed.yaml +++ /dev/null @@ -1,36 +0,0 @@ -Keys: - Asymmetric: - Rsa: - - Metadata: - KeyId: ff275b92-0def-4dfc-b0f6-87c96b26c6c7 - KeyUsage: SIGN_VERIFY # or ENCRYPT_DECRYPT - Description: RSA key with 2048 bits - PrivateKeyPem: | - -----BEGIN PRIVATE KEY----- - MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCa/AHjWojkV7jU - 8Ntepxfm469K98qHyX1BXQ7cz42wHiUqpAQ/S3WF+iJdOk6ArPUCtjEexDYt5eJ9 - fi7ARtgkWWlUz63JCRNZCME7Dp+wtgrZeThfbKU1dRR/vHdIOI5XHK9OHc5lb2Sq - sME30nFKito0vJ/DSGFbRIel+zr31J6GBtDtBZ6n+BWUpEsjPRcBdpk3Dbizv05F - xCWsITpgPQ+BCakj90rnEwwvzafrLepxOXLCUZpTs4Ygx0P4JNcDcFw6SBd6plNc - 1pfW7qMJNrWW8BzO6fpq+nlVnhMWK4+j7LisncZT7XhzJPk1yQRxpMpK93zpR3Ar - kh322XdtAgMBAAECggEAC+C3Hv7X8Z1szkUMoEXGEIKanfA9AV3Gel/wvP4wfwg7 - E6LbqyN+r58/9aJ7qbjs/iGLGi8yHR+6f/ZPtu9hrpzQ9G2w2ptrdC4Llm8Z0Kfi - +k/Oq4w0DSjFQr+QP2S2OU7lezh656M7NSm0D9x8+kLcqPYGeHzvmS24slZ9anOD - ymADxcicF2V1LHrl1I4CpUJarAO19tX+OXq86bB28fAdC1++33r1ERC2uZrTGIyj - MN6t2DMX98MYg4QHfNBArPP3rwoOvtSa9fssnqOVGhqGysDrVcfycmdfj2PuGisP - BMU0Wk85lRzyjMbzFS9q8BdVwtjGH9htHT28MMWugQKBgQDYaoqH/dm59qOtNvbw - NlPYEiHMdjQpoLFBwrxHQD9hYjXdu9leRjEdR78s0kC23zDQzsQ4rpIj1glO9LwZ - USUlWtRRkLZ/8d1DvJERUQGFlHBLpgB8ikapSnijo4zT1Jw6s348YSEqyh1McTsn - o+zL2Fra8vvI4YwsIUphUtKhiQKBgQC3VP0GYQzxzvLbqSzufc6UMTM7Vk4kluWP - ORxWnk4kKv8owgW0LHHhtiOQjRxMakLFW2nxfI9oWIoOmoRAbJFSQFQKglX4IExV - bHI+3s5Gas3X+AS5ANoUdMBBrUSvAkyamv8LTfRsj8ztVGgXw51JAHhS/uVuaLbe - FdLpOsyhxQKBgQCYIrWGCi8f6sF/SA9qKFbio0R9Tm83AE77sqDW2dR0ai0B1kdl - XaSzN7euE5QIune/oksQqa/0X0el6Ke+iGu7idGOEVQqN2Xbc1jrum1+cS5MD8Nx - yWcJJWAPcS7TzzeQkJPicEl3oiPclBEIudUCK/MazguwWNZIQ5LdPfLyOQKBgF+G - ZSDByODmGBzklYje/Jiy2iL84VKnXY23EFEBw22NCc7O6fHrhps5MGbNYAVhCNGU - xCsT4BVarPTXBjobV80nv6KKLwlOqveHvi+MIKcIV6FElhFfpEIsY1DVW4hlBk04 - ndPiFo3Kj9jJtkNLpdS37fow3pMc9MvbSz5DaQSRAoGATiUvoT5mQB98RtJT3Up4 - 75/7DTBJVpzXPHbxF0BCSYgutKv6aXXgEFO680Lu7TVNKDbBJIJXPIas2y4uYdNJ - LcaqO3kx1JhTHTxRokTBVH3vyiFWKMGXZ0UYXBpeQoWNezxLJea8Cp3sEgbw+jaB - uRm76Xvsh0JZ5MDgy26hFVs= - -----END PRIVATE KEY----- diff --git a/e2e/e2e.sh b/e2e/e2e.sh deleted file mode 100644 index 9c7bee628..000000000 --- a/e2e/e2e.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -set -x -# to facilitate local test - -# common configs for all enclaves -NGROK_TOKEN= -CORE_VERSION=2.15.0-50d596678a-default -OPTOUT_VERSION=2.6.18-60727cf243-default - -# GCP OIDC enclave configs -TEST_GCP_OIDC=true -# starts with sha256: -IMAGE_HASH=sha256: -GCP_PROJECT=uid2-test -SERVICE_ACCOUNT='github-ci@uid2-test.iam.gserviceaccount.com' - -# Azure CC enclave configs -TEST_AZURE_CC=false -IMAGE_VERSION= - -# replace below with your local repo root of uid2-core and uid2-optout -CORE_ROOT="../../uid2-core" -OPTOUT_ROOT="../../uid2-optout" - -# copy to a different folder in local to avoid data pollution -rm -rf "./e2e-target" -cp -rf "./e2e/" "./e2e-target" - -cd ./e2e-target - -killall ngrok -docker compose down - -source ./prepare_conf.sh -source ./setup_ngrok.sh - -if [ "$TEST_GCP_OIDC" = true ]; then - source ./prepare_gcp_enclave_metadata.sh -fi - -if [ "$TEST_AZURE_CC" = true ]; then - source ./prepare_azure_cc_artifacts.sh - source ./prepare_azure_cc_enclave_metadata.sh -fi - -source ./start_docker.sh - -if [ "$TEST_GCP_OIDC" = true ]; then - source ./start_gcp_enclave.sh - #source ./stop_gcp_enclave.sh -fi - -if [ "$TEST_AZURE_CC" = true ]; then - source ./start_azure_cc_enclave.sh - #source ./stop_azure_cc_enclave.sh -fi diff --git a/e2e/healthcheck.sh b/e2e/healthcheck.sh deleted file mode 100644 index 9e9f383bb..000000000 --- a/e2e/healthcheck.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -healthcheck() { - attempt_counter=0 - max_attempts=5 - if [ -n "$2" ]; then - max_attempts=$2 - fi - echo "Healthcheck $1 for $max_attempts times" - - until (curl -m 5 --output /dev/null --silent --fail "$1"); do - if [ -n "$3" ]; then - docker compose logs --tail 100 - fi - - if [ $attempt_counter -eq $max_attempts ];then - echo "Max attempts reached" - exit 1 - fi - - printf '.' - attempt_counter=$((attempt_counter+1)) - sleep 5 - done - echo "Healthcheck $1 succeed." -} diff --git a/e2e/jq_helper.sh b/e2e/jq_helper.sh deleted file mode 100644 index f7266e8c8..000000000 --- a/e2e/jq_helper.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -# for string -# https://jqlang.github.io/jq/manual/ -# --arg foo 123 will bind $foo to "123". -function jq_inplace_update() { - local file=$1 - local field=$2 - local value=$3 - jq --arg v "$value" ".$field = \$v" "$file" > tmp.json && mv tmp.json "$file" -} - -# for number/boolean -# https://jqlang.github.io/jq/manual/ -# --argjson foo 123 will bind $foo to 123. -function jq_inplace_update_json() { - local file=$1 - local field=$2 - local value=$3 - jq --argjson v "$value" ".$field = \$v" "$file" > tmp.json && mv tmp.json "$file" -} diff --git a/e2e/ngrok.yml b/e2e/ngrok.yml deleted file mode 100644 index 245d29519..000000000 --- a/e2e/ngrok.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: "2" -authtoken: -tunnels: - localstack: - addr: 5001 - proto: http - optout: - addr: 8081 - proto: http - core: - addr: 8088 - proto: http diff --git a/e2e/prepare_azure_cc_artifacts.sh b/e2e/prepare_azure_cc_artifacts.sh deleted file mode 100644 index 3d1c02431..000000000 --- a/e2e/prepare_azure_cc_artifacts.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -set -ex - -INPUT_DIR="./azure" -OUT_PUT_DIR="./azure-artifacts" - -if [ -z "$IMAGE_VERSION" ]; then - echo "IMAGE_VERSION can not be empty" - exit 1 -fi - -IMAGE="ghcr.io/iabtechlab/uid2-operator:$IMAGE_VERSION" - -if [ -d "$OUT_PUT_DIR" ]; then - echo "$OUT_PUT_DIR exist." -fi - -INPUT_TEMPLATE_FILE="$INPUT_DIR/template.json" -INPUT_PARAMETERS_FILE="$INPUT_DIR/parameters.json" -OUTPUT_TEMPLATE_FILE="$OUT_PUT_DIR/template.json" -OUTPUT_PARAMETERS_FILE="$OUT_PUT_DIR/parameters.json" -OUTPUT_POLICY_DIGEST_FILE="$OUT_PUT_DIR/digest.txt" - -if [[ -d $OUT_PUT_DIR ]]; then - echo "$OUT_PUT_DIR exist. Skip. This only happens during local test." -else - mkdir -p $OUT_PUT_DIR - - # Install confcom extension, az is originally available in GitHub workflow environment - az extension add --name confcom - if [[ $? -ne 0 ]]; then - echo "Failed to install Azure confcom extension" - exit 1 - fi - - # Required by az confcom - sudo usermod -aG docker $USER - if [[ $? -ne 0 ]]; then - echo "Failed to add current user to docker group" - exit 1 - fi - - # Generate deployment template - cp $INPUT_TEMPLATE_FILE $OUTPUT_TEMPLATE_FILE - sed -i "s#IMAGE_PLACEHOLDER#$IMAGE#g" $OUTPUT_TEMPLATE_FILE - if [[ $? -ne 0 ]]; then - echo "Failed to pre-process template file" - exit 1 - fi - - az confcom acipolicygen --approve-wildcards --template-file $OUTPUT_TEMPLATE_FILE > $OUTPUT_POLICY_DIGEST_FILE - if [[ $? -ne 0 ]]; then - echo "Failed to generate template file" - exit 1 - fi - - cp $INPUT_PARAMETERS_FILE $OUTPUT_PARAMETERS_FILE -fi - -if [ -z "$GITHUB_OUTPUT" ]; then - echo "not in github action" -else - echo "OUTPUT_TEMPLATE_FILE=$OUTPUT_TEMPLATE_FILE" >> $GITHUB_OUTPUT - echo "OUTPUT_PARAMETERS_FILE=$OUTPUT_PARAMETERS_FILE" >> $GITHUB_OUTPUT - echo "OUTPUT_POLICY_DIGEST_FILE=$OUTPUT_POLICY_DIGEST_FILE" >> $GITHUB_OUTPUT -fi diff --git a/e2e/prepare_azure_cc_enclave_metadata.sh b/e2e/prepare_azure_cc_enclave_metadata.sh deleted file mode 100644 index 5a3f2fb8e..000000000 --- a/e2e/prepare_azure_cc_enclave_metadata.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -METADATA_ROOT="$ROOT/docker/localstack/s3/core" -OPERATOR_FILE="$METADATA_ROOT/operators/operators.json" -ENCLAVE_FILE="$METADATA_ROOT/enclaves/enclaves.json" - -if [[ ! -f $OUTPUT_POLICY_DIGEST_FILE ]]; then - echo "OUTPUT_POLICY_DIGEST_FILE does not exist" - exit 1 -fi - -AZURE_CC_POLICY_DIGEST="$(cat $OUTPUT_POLICY_DIGEST_FILE)" - -echo "AZURE_CC_POLICY_DIGEST=$AZURE_CC_POLICY_DIGEST" - -enclave_id=$AZURE_CC_POLICY_DIGEST - -# fetch operator key -OPERATOR_KEY=$(jq -r '.[] | select(.protocol=="azure-cc") | .key' $OPERATOR_FILE) - -# update azure-cc enclave id -cat <<< $(jq '(.[] | select(.protocol=="azure-cc") | .identifier) |='\"$enclave_id\"'' $ENCLAVE_FILE) > $ENCLAVE_FILE - -# export to Github output -echo "OPERATOR_KEY=$OPERATOR_KEY" - -if [ -z "$GITHUB_OUTPUT" ]; then - echo "not in github action" -else - echo "OPERATOR_KEY=$OPERATOR_KEY" >> $GITHUB_OUTPUT -fi diff --git a/e2e/prepare_conf.sh b/e2e/prepare_conf.sh deleted file mode 100644 index cf1489a1a..000000000 --- a/e2e/prepare_conf.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -CORE_CONFIG_FILE_DIR="$ROOT/docker/uid2-core/conf" -OPTOUT_CONFIG_FILE_DIR="$ROOT/docker/uid2-optout/conf" - -if [ -z "$CORE_ROOT" ]; then - echo "CORE_ROOT can not be empty" - exit 1 -fi - -if [ -z "$OPTOUT_ROOT" ]; then - echo "$OPTOUT_ROOT can not be empty" - exit 1 -fi - -mkdir -p "$CORE_CONFIG_FILE_DIR" && cp "$CORE_ROOT/conf/local-e2e-docker-config.json" "$CORE_CONFIG_FILE_DIR" -mkdir -p "$OPTOUT_CONFIG_FILE_DIR" && cp "$OPTOUT_ROOT/conf/local-e2e-docker-config.json" "$OPTOUT_CONFIG_FILE_DIR" diff --git a/e2e/prepare_gcp_enclave_metadata.sh b/e2e/prepare_gcp_enclave_metadata.sh deleted file mode 100755 index 96ff3f658..000000000 --- a/e2e/prepare_gcp_enclave_metadata.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -METADATA_ROOT="$ROOT/docker/localstack/s3/core" -OPERATOR_FILE="$METADATA_ROOT/operators/operators.json" -ENCLAVE_FILE="$METADATA_ROOT/enclaves/enclaves.json" - -if [ -z "$IMAGE_HASH" ]; then - echo "IMAGE_HASH can not be empty" - exit 1 -fi - -# generate enclave id -enclave_str="V1,true,$IMAGE_HASH" -echo "enclave_str=$enclave_str" -enclave_id=$(echo -n $enclave_str | openssl dgst -sha256 -binary | openssl base64) - - -# fetch operator key -OPERATOR_KEY=$(jq -r '.[] | select(.protocol=="gcp-oidc") | .key' $OPERATOR_FILE) - -# update gcp-oidc enclave id -cat <<< $(jq '(.[] | select(.protocol=="gcp-oidc") | .identifier) |='\"$enclave_id\"'' $ENCLAVE_FILE) > $ENCLAVE_FILE - -# export to Github output -echo "OPERATOR_KEY=$OPERATOR_KEY" - -if [ -z "$GITHUB_OUTPUT" ]; then - echo "not in github action" -else - echo "OPERATOR_KEY=$OPERATOR_KEY" >> $GITHUB_OUTPUT -fi diff --git a/e2e/setup_ngrok.sh b/e2e/setup_ngrok.sh deleted file mode 100755 index f614c077b..000000000 --- a/e2e/setup_ngrok.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -NGROK_TMPL_PATH="$ROOT/ngrok.yml" -TUNNEL_URL="http://127.0.0.1:4040/api/tunnels" - -if [ -z "$NGROK_TOKEN" ]; then - echo "NGROK_TOKEN can not be empty" - exit 1 -fi - -# install -ngrok_cmd="ngrok" -if ! which ngrok > /dev/null; then - echo "ngrok not found!" - wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz - tar xvzf ngrok-v3-stable-linux-amd64.tgz - ngrok_cmd="./ngrok" -fi - -# update config file -sed -i.bak "s//$NGROK_TOKEN/g" $NGROK_TMPL_PATH - -# start and check endpoint -$ngrok_cmd --config $NGROK_TMPL_PATH start --all > /dev/null & - -source "$ROOT/healthcheck.sh" -healthcheck $TUNNEL_URL - -# parse public url -tunnel_info=$(curl -s $TUNNEL_URL) - -echo $tunnel_info - -NGROK_URL_LOCALSTACK=$(jq -r '.tunnels | .[] | select(.name=="localstack") | .public_url' <<< "$tunnel_info") -NGROK_URL_CORE=$(jq -r '.tunnels | .[] | select(.name=="core") | .public_url' <<< "$tunnel_info") -NGROK_URL_OPTOUT=$(jq -r '.tunnels | .[] | select(.name=="optout") | .public_url' <<< "$tunnel_info") - -# export to Github output -echo "NGROK_URL_LOCALSTACK=$NGROK_URL_LOCALSTACK" -echo "NGROK_URL_CORE=$NGROK_URL_CORE" -echo "NGROK_URL_OPTOUT=$NGROK_URL_OPTOUT" - -if [ -z "$GITHUB_OUTPUT" ]; then - echo "not in github action" -else - echo "NGROK_URL_LOCALSTACK=$NGROK_URL_LOCALSTACK" >> $GITHUB_OUTPUT - echo "NGROK_URL_CORE=$NGROK_URL_CORE" >> $GITHUB_OUTPUT - echo "NGROK_URL_OPTOUT=$NGROK_URL_OPTOUT" >> $GITHUB_OUTPUT -fi diff --git a/e2e/start_azure_cc_enclave.sh b/e2e/start_azure_cc_enclave.sh deleted file mode 100644 index 6343262ef..000000000 --- a/e2e/start_azure_cc_enclave.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -# below resources should be prepared ahead -RESOURCE_GROUP=uid-enclave-ci-cd -IDENTITY=uid-operator -VAULT_NAME=uid-operator -OPERATOR_KEY_NAME=operator-key-ci - -LOCATION="East US" -DEPLOYMENT_ENV="integ" -CONTAINER_GROUP_NAME="ci-test-$RANDOM" -DEPLOYMENT_NAME=$CONTAINER_GROUP_NAME - -source "$ROOT/jq_helper.sh" -source "$ROOT/healthcheck.sh" - -if [ -z "$IDENTITY" ]; then - echo "IDENTITY can not be empty" - exit 1 -fi - -if [ -z "$VAULT_NAME" ]; then - echo "VAULT_NAME can not be empty" - exit 1 -fi - -if [ -z "$OPERATOR_KEY_NAME" ]; then - echo "OPERATOR_KEY_NAME can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_CORE" ]; then - echo "NGROK_URL_CORE can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_OPTOUT" ]; then - echo "NGROK_URL_OPTOUT can not be empty" - exit 1 -fi - -if [[ ! -f $OUTPUT_TEMPLATE_FILE ]]; then - echo "OUTPUT_TEMPLATE_FILE does not exist" - exit 1 -fi - -if [[ ! -f $OUTPUT_PARAMETERS_FILE ]]; then - echo "OUTPUT_PARAMETERS_FILE does not exist" - exit 1 -fi - -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.containerGroupName.value "$CONTAINER_GROUP_NAME" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.location.value "$LOCATION" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.identity.value "$IDENTITY" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.vaultName.value "$VAULT_NAME" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.operatorKeySecretName.value "$OPERATOR_KEY_NAME" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.deploymentEnvironment.value "$DEPLOYMENT_ENV" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.coreBaseUrl.value "$NGROK_URL_CORE" -jq_inplace_update $OUTPUT_PARAMETERS_FILE parameters.optoutBaseUrl.value "$NGROK_URL_OPTOUT" - -cat $OUTPUT_PARAMETERS_FILE - -az deployment group create \ - -g $RESOURCE_GROUP \ - -n $DEPLOYMENT_NAME \ - --template-file "$OUTPUT_TEMPLATE_FILE" \ - --parameters "$OUTPUT_PARAMETERS_FILE" - -# export to Github output -echo "CONTAINER_GROUP_NAME=$CONTAINER_GROUP_NAME" - -if [ -z "$GITHUB_OUTPUT" ]; then - echo "not in github action" -else - echo "CONTAINER_GROUP_NAME=$CONTAINER_GROUP_NAME" >> $GITHUB_OUTPUT -fi - -# get public IP, need to trim quotes -ip=$(az deployment group show \ - -g $RESOURCE_GROUP \ - -n $DEPLOYMENT_NAME \ - --query properties.outputs.containerIPv4Address.value | tr -d '"') - -echo "instance ip: $ip" - -healthcheck_url="http://$ip:8080/ops/healthcheck" - -# health check - for 5 mins -healthcheck "$healthcheck_url" 60 diff --git a/e2e/start_docker.sh b/e2e/start_docker.sh deleted file mode 100644 index d28eca337..000000000 --- a/e2e/start_docker.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -CORE_CONFIG_FILE="$ROOT/docker/uid2-core/conf/local-e2e-docker-config.json" -OPTOUT_CONFIG_FILE="$ROOT/docker/uid2-optout/conf/local-e2e-docker-config.json" -COMPOSE_FILE="$ROOT/docker-compose.yml" -OPTOUT_MOUNT="$ROOT/docker/uid2-optout/mount" -OPTOUT_HEALTHCHECK_URL="$NGROK_URL_OPTOUT/ops/healthcheck" - -source "$ROOT/jq_helper.sh" -source "$ROOT/healthcheck.sh" - -if [ -z "$CORE_VERSION" ]; then - echo "CORE_VERSION can not be empty" - exit 1 -fi - -if [ -z "$OPTOUT_VERSION" ]; then - echo "OPTOUT_VERSION can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_LOCALSTACK" ]; then - echo "NGROK_URL_LOCALSTACK can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_CORE" ]; then - echo "NGROK_URL_CORE can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_OPTOUT" ]; then - echo "NGROK_URL_OPTOUT can not be empty" - exit 1 -fi - -# replace placeholders -sed -i.bak "s##$CORE_VERSION#g" $COMPOSE_FILE -sed -i.bak "s##$OPTOUT_VERSION#g" $COMPOSE_FILE - -# set provide_private_site_data to false to workaround the private site path -jq_inplace_update $CORE_CONFIG_FILE aws_s3_endpoint "$NGROK_URL_LOCALSTACK" -jq_inplace_update $CORE_CONFIG_FILE kms_aws_endpoint "$NGROK_URL_LOCALSTACK" -jq_inplace_update $CORE_CONFIG_FILE core_public_url "$NGROK_URL_CORE" -jq_inplace_update $CORE_CONFIG_FILE optout_url "$NGROK_URL_OPTOUT" -jq_inplace_update_json $CORE_CONFIG_FILE provide_private_site_data false - -jq_inplace_update $OPTOUT_CONFIG_FILE aws_s3_endpoint "$NGROK_URL_LOCALSTACK" -jq_inplace_update $OPTOUT_CONFIG_FILE partners_metadata_path "$NGROK_URL_CORE/partners/refresh" -jq_inplace_update $OPTOUT_CONFIG_FILE operators_metadata_path "$NGROK_URL_CORE/operators/refresh" -jq_inplace_update $OPTOUT_CONFIG_FILE core_attest_url "$NGROK_URL_CORE/attest" -jq_inplace_update $OPTOUT_CONFIG_FILE core_public_url "$NGROK_URL_CORE" -jq_inplace_update $OPTOUT_CONFIG_FILE optout_url "$NGROK_URL_OPTOUT" - -cat $CORE_CONFIG_FILE -cat $OPTOUT_CONFIG_FILE - -mkdir -p "$OPTOUT_MOUNT" && chmod 777 "$OPTOUT_MOUNT" - -docker compose -f "$ROOT/docker-compose.yml" up -d -docker ps -a - -# health check - for 5 mins -healthcheck "$OPTOUT_HEALTHCHECK_URL" 60 1 diff --git a/e2e/start_gcp_enclave.sh b/e2e/start_gcp_enclave.sh deleted file mode 100644 index 1363363d3..000000000 --- a/e2e/start_gcp_enclave.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env bash -set -ex - -ROOT="." -GCP_INSTANCE_NAME="ci-test-$RANDOM" -OPERATOR_KEY_SECRET_NAME=$GCP_INSTANCE_NAME - -source "$ROOT/healthcheck.sh" - -if [ -z "$GCP_PROJECT" ]; then - echo "GCP_PROJECT can not be empty" - exit 1 -fi - -if [ -z "$SERVICE_ACCOUNT" ]; then - echo "SERVICE_ACCOUNT can not be empty" - exit 1 -fi - -if [ -z "$IMAGE_HASH" ]; then - echo "IMAGE_HASH can not be empty" - exit 1 -fi - -if [ -z "$OPERATOR_KEY" ]; then - echo "OPERATOR_KEY can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_CORE" ]; then - echo "NGROK_URL_CORE can not be empty" - exit 1 -fi - -if [ -z "$NGROK_URL_OPTOUT" ]; then - echo "NGROK_URL_OPTOUT can not be empty" - exit 1 -fi - -gcloud config set project $GCP_PROJECT - -gcloud config set compute/zone asia-southeast1-a - -# create secret -echo -n "$OPERATOR_KEY" | gcloud secrets create $OPERATOR_KEY_SECRET_NAME \ - --replication-policy="automatic" \ - --data-file=- - -OPERATOR_KEY_SECRET_VERSION=$(gcloud secrets versions describe latest --secret $OPERATOR_KEY_SECRET_NAME --format 'value(name)') - -gcloud compute instances create $GCP_INSTANCE_NAME \ - --confidential-compute \ - --shielded-secure-boot \ - --maintenance-policy Terminate \ - --scopes cloud-platform \ - --image-project confidential-space-images \ - --image-family confidential-space-debug \ - --service-account $SERVICE_ACCOUNT \ - --metadata ^~^tee-image-reference=us-docker.pkg.dev/uid2-prod-project/iabtechlab/uid2-operator@$IMAGE_HASH~tee-restart-policy=Never~tee-container-log-redirect=true~tee-env-DEPLOYMENT_ENVIRONMENT=integ~tee-env-API_TOKEN_SECRET_NAME=$OPERATOR_KEY_SECRET_VERSION~tee-env-CORE_BASE_URL=$NGROK_URL_CORE~tee-env-OPTOUT_BASE_URL=$NGROK_URL_OPTOUT - -# export to Github output -echo "GCP_INSTANCE_NAME=$GCP_INSTANCE_NAME" - -if [ -z "$GITHUB_OUTPUT" ]; then - echo "not in github action" -else - echo "GCP_INSTANCE_NAME=$GCP_INSTANCE_NAME" >> $GITHUB_OUTPUT -fi - -# get public IP -ip=$(gcloud compute instances describe $GCP_INSTANCE_NAME \ - --format='get(networkInterfaces[0].accessConfigs[0].natIP)') - -echo "instance ip: $ip" - -healthcheck_url="http://$ip:8080/ops/healthcheck" - -# health check - for 5 mins -healthcheck "$healthcheck_url" 60 diff --git a/e2e/stop_azure_cc_enclave.sh b/e2e/stop_azure_cc_enclave.sh deleted file mode 100644 index 4dfdc1ad2..000000000 --- a/e2e/stop_azure_cc_enclave.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -set -ex - -RESOURCE_GROUP=uid-enclave-ci-cd - -if [ -z "$CONTAINER_GROUP_NAME" ]; then - echo "CONTAINER_GROUP_NAME can not be empty" - exit 1 -fi - -az container delete \ - -g $RESOURCE_GROUP \ - -n $CONTAINER_GROUP_NAME -y diff --git a/e2e/stop_gcp_enclave.sh b/e2e/stop_gcp_enclave.sh deleted file mode 100644 index dc82d6cf3..000000000 --- a/e2e/stop_gcp_enclave.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -ex - -if [ -z "$GCP_PROJECT" ]; then - echo "GCP_PROJECT can not be empty" - exit 1 -fi - -if [ -z "$SERVICE_ACCOUNT" ]; then - echo "SERVICE_ACCOUNT can not be empty" - exit 1 -fi - -if [ -z "$GCP_INSTANCE_NAME" ]; then - echo "GCP_INSTANCE_NAME can not be empty" - exit 1 -fi - -OPERATOR_KEY_SECRET_NAME=$GCP_INSTANCE_NAME - -gcloud config set project $GCP_PROJECT - -gcloud config set compute/zone asia-southeast1-a - -gcloud compute instances delete $GCP_INSTANCE_NAME --quiet - -gcloud secrets delete $OPERATOR_KEY_SECRET_NAME --quiet From 3f255863069a723b3d8c925e775c6c54634d8e63 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Fri, 23 Feb 2024 11:49:34 +1100 Subject: [PATCH 0132/1116] UID2-2772 enable e2e tests (#361) * Test on custom branch * Remove `enforce_https` override * Use v2 shared action * Use custom branch * Remove unnecessary change * Use v2 of shared-action * Use kcc-UID2-2772-enable-e2e-tests branch * Revert kcc-UID2-2772-enable-e2e-tests to v2 * Remove remainging skip_e2e_test --- .github/workflows/publish-all-operators.yaml | 6 ------ .github/workflows/publish-aws-nitro-enclave-docker.yaml | 8 -------- 2 files changed, 14 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index b3ea593d4..f452d431b 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -10,10 +10,6 @@ on: - Major - Minor - Patch - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false jobs: start: @@ -85,7 +81,6 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} - skip_e2e_test: ${{ inputs.skip_e2e_test }} secrets: inherit buildAzure: @@ -95,7 +90,6 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} - skip_e2e_test: ${{ inputs.skip_e2e_test }} secrets: inherit collectAllArtifacts: diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 6498cc060..e2649537a 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -15,10 +15,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false workflow_call: inputs: release_type: @@ -29,10 +25,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - skip_e2e_test: - description: If true, will skip the step for E2E tests - type: boolean - default: false jobs: buildImage: From 1e3563052bdf5ed6ce7d61d1d43cdf6ad0fe5411 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 23 Feb 2024 00:50:30 +0000 Subject: [PATCH 0133/1116] Released Patch version: 5.27.10-3f25586306 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 94de38804..d8e45df87 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.6-396bb357e3 + 5.27.10-3f25586306 UTF-8 From ee42ae24d2d6d31c1b02357920dd0225d88488eb Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 23 Feb 2024 13:50:03 +1100 Subject: [PATCH 0134/1116] Added error handling on OptOutCloudStorage --- .../uid2/operator/store/CloudSyncOptOutStore.java | 1 + .../uid2/operator/store/OptOutCloudStorage.java | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index a7239f65d..1df9c917b 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -83,6 +83,7 @@ public void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, return; } + LOGGER.debug("CloudSyncOptOutStore calling endpoint: {}", remoteApiHost); this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath). addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.id)) .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) diff --git a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java index fdc76051a..3e1da17a6 100644 --- a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java +++ b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java @@ -5,14 +5,19 @@ import com.uid2.shared.cloud.CloudStorageException; import com.uid2.shared.cloud.URLStorageWithMetadata; import com.uid2.shared.optout.OptOutMetadata; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.net.Proxy; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class OptOutCloudStorage extends URLStorageWithMetadata { + private static final Logger LOGGER = LoggerFactory.getLogger(OptOutCloudStorage.class); + private final UidOptOutClient uidOptOutClient; private final String metadataPath; @@ -29,8 +34,14 @@ public OptOutCloudStorage(UidOptOutClient uidOptOutClient, String metadataPath, @Override protected List extractListFromMetadata() throws CloudStorageException { try (InputStream input = this.uidOptOutClient.download(metadataPath)) { - OptOutMetadata m = OptOutMetadata.fromJsonString(Utils.readToEnd(input)); - return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); + String jsonString = Utils.readToEnd(input); + if (jsonString != null && !jsonString.isEmpty()) { + OptOutMetadata m = OptOutMetadata.fromJsonString(Utils.readToEnd(input)); + return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); + } else { + LOGGER.warn("Empty string returned from UidOptOutClient. Unable to read OptOut metadata"); + return new ArrayList(); + } } catch (IOException e) { throw new CloudStorageException("extractListFromMetadata error" + e.getMessage(), e); } From 1fe35ed377e0296bb870637de3722e3016d4c004 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 23 Feb 2024 13:53:09 +1100 Subject: [PATCH 0135/1116] Merged main --- e2e/ngrok.yml | 12 ++++++++++++ scripts/aws/UID_CloudFormation.template.yml | 3 +-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 e2e/ngrok.yml diff --git a/e2e/ngrok.yml b/e2e/ngrok.yml new file mode 100644 index 000000000..081d3fdd8 --- /dev/null +++ b/e2e/ngrok.yml @@ -0,0 +1,12 @@ +version: "2" +authtoken: 20IKxrKo9AT4GNovcz2Z10v4k2c_7aYZHCXL2puu8sBdefhh1 +tunnels: + localstack: + addr: 5001 + proto: http + optout: + addr: 8081 + proto: http + core: + addr: 8088 + proto: http diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index 5c43450fb..4fc34159a 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -31,7 +31,6 @@ Parameters: - m5a.4xlarge - m5n.2xlarge - m5n.4xlarge - ConstraintDescription: must be a valid EC2 instance type. RootVolumeSize: Description: Instance root volume size Type: Number @@ -103,7 +102,7 @@ Metadata: Mappings: RegionMap: us-east-1: - AMI: ami-xxxxxxxxxxxxxxxxx + AMI: ami-069965aca2f4bb943 us-east-2: AMI: ami-xxxxxxxxxxxxxxxxx us-west-1: From e2c49bf6fb33beeea377bdd5999f9769ca4da00b Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 22 Feb 2024 14:30:20 +0800 Subject: [PATCH 0136/1116] Fixed Makefile --- .github/actions/build_aws_eif/action.yaml | 9 ++- Makefile.nitro | 86 ++++++--------------- scripts/aws/pipeline/amazonlinux.Dockerfile | 15 +++- scripts/aws/pipeline/aws_nitro_eif.sh | 21 ++++- 4 files changed, 62 insertions(+), 69 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 59bac1143..837bb760f 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -42,6 +42,7 @@ runs: shell: bash run: | ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" + mkdir -p ${ARTIFACTS_OUTPUT_DIR} cp ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt ${ARTIFACTS_OUTPUT_DIR}/ @@ -53,7 +54,7 @@ runs: cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/ - docker cp amazonlinux:/build/uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ${ARTIFACTS_OUTPUT_DIR}/vsockpx - docker cp amazonlinux:/build/dante-1.4.3/sockd/sockd ${ARTIFACTS_OUTPUT_DIR}/ - docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ - docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/Makefile.nitro b/Makefile.nitro index a2e36b8e0..946d845cb 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -2,67 +2,25 @@ CONFIG_DIR=/etc/uid2operator DATA_DIR=/opt/uid2operator .PHONY: all -all: build_eif - -################################################################################################################################################################## - -# Base - -install: ./build/uid2operator.eif ./build/dante-1.4.3/sockd ./build/uid2-aws-enclave-vsockproxy/build/vsock-bridge ./scripts/aws/start.sh ./scripts/aws/stop.sh ./scripts/aws/allocator.template.yaml ./scripts/aws/proxies.host.yaml ./scripts/aws/uid2operator.service - mkdir -p $(CONFIG_DIR) - mkdir -p $(DATA_DIR) - cp ./scripts/aws/proxies.host.yaml $(CONFIG_DIR)/proxy.yaml - cp ./scripts/aws/allocator.template.yaml $(CONFIG_DIR)/ - cp ./build/uid2operator.eif $(DATA_DIR)/ - cp ./scripts/aws/start.sh $(DATA_DIR)/start.sh - cp ./scripts/aws/stop.sh $(DATA_DIR)/stop.sh - cp ./scripts/aws/sockd.conf /etc/ - cp ./scripts/aws/uid2operator.service /etc/systemd/system/ - cp ./build/uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge /usr/bin/vsockpx - cp ./build/dante-1.4.3/sockd/sockd /usr/bin/ - chmod +x /usr/bin/vsockpx - -uninstall: - rm -rf $(CONFIG_DIR) - rm -rf $(DATA_DIR) - rm /usr/bin/vsockpx - rm /etc/systemd/system/uid2operator.service - -clean: - rm -rf build - -################################################################################################################################################################## -# Dependencies - -./build/dante-1.4.3/sockd: - cd build; wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz - cd build; echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum - cd build; sha256sum --check dante_checksum - cd build; tar -xf dante-1.4.3.tar.gz - cd build/dante-1.4.3; ./configure - cd build/dante-1.4.3; make - -./build/uid2-aws-enclave-vsockproxy/build/vsock-bridge: - cd build; git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git - cd build/uid2-aws-enclave-vsockproxy; mkdir -p build/ - cd build/uid2-aws-enclave-vsockproxy/build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo - cd build/uid2-aws-enclave-vsockproxy/build; make +all: build_eif ################################################################################################################################################################## # EIF -build_eif: uid2operator.eif euidoperator.eif +.PHONY: build_eif -euidoperator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py - cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./euidoperator.tar euidoperator; docker cp ./euidoperator.tar amazonlinux:/euidoperator.tar - docker exec amazonlinux bash aws_nitro_eif.sh euidoperator +build_eif: uid2operator.eif euidoperator.eif -uid2operator.eif: build_artifacts build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/configs build/load_config.py build/make_config.py +uid2operator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./uid2operator.tar uid2operator; docker cp ./uid2operator.tar amazonlinux:/uid2operator.tar docker exec amazonlinux bash aws_nitro_eif.sh uid2operator +euidoperator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py + cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./euidoperator.tar euidoperator; docker cp ./euidoperator.tar amazonlinux:/euidoperator.tar + docker exec amazonlinux bash aws_nitro_eif.sh euidoperator + ################################################################################################################################################################## # Config scripts @@ -75,27 +33,29 @@ build/make_config.py: ./scripts/aws/make_config.py ################################################################################################################################################################## -# Artifacts +# Configs + +.PHONY: build_configs -build/configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.loki.xml +build_configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.loki.xml build/conf/default-config.json: build_artifacts ./scripts/aws/conf/default-config.json - cp ./scripts/aws/conf/default-config.json ./build/conf/default-config.json + cp ./scripts/aws/conf/default-config.json ./build/conf/ build/conf/prod-uid2-config.json: build_artifacts ./scripts/aws/conf/prod-uid2-config.json - cp ./scripts/aws/conf/prod-uid2-config.json ./build/conf/prod-uid2-config.json + cp ./scripts/aws/conf/prod-uid2-config.json ./build/conf/ build/conf/prod-euid-config.json: build_artifacts ./scripts/aws/conf/prod-euid-config.json - cp ./scripts/aws/conf/prod-euid-config.json ./build/conf/prod-euid-config.json + cp ./scripts/aws/conf/prod-euid-config.json ./build/conf/ build/conf/integ-uid2-config.json: build_artifacts ./scripts/aws/conf/integ-uid2-config.json - cp ./scripts/aws/conf/integ-uid2-config.json ./build/conf/integ-uid2-config.json + cp ./scripts/aws/conf/integ-uid2-config.json ./build/conf/ build/conf/integ-euid-config.json: build_artifacts ./scripts/aws/conf/integ-euid-config.json - cp ./scripts/aws/conf/integ-euid-config.json ./build/conf/integ-euid-config.json + cp ./scripts/aws/conf/integ-euid-config.json ./build/conf/ build/conf/logback.loki.xml: build_artifacts ./scripts/aws/conf/logback.loki.xml - cp ./scripts/aws/conf/logback.loki.xml ./build/conf/logback.loki.xml + cp ./scripts/aws/conf/logback.loki.xml ./build/conf/ build/Dockerfile: build_artifacts ./scripts/aws/Dockerfile cp ./scripts/aws/Dockerfile ./build/ @@ -106,14 +66,18 @@ build/proxies.nitro.yaml: build_artifacts ./scripts/aws/proxies.nitro.yaml build/entrypoint.sh: build_artifacts cp ./scripts/aws/entrypoint.sh ./build/ +################################################################################################################################################################## + +# Artifacts + +.PHONY: build_artifacts + build_artifacts: build/build_artifacts.stamp -build/build_artifacts.stamp build/vsockpx build/libjnsm.so: Dockerfile.nitro.builder +build/build_artifacts.stamp: Dockerfile.nitro.builder docker build -t uid2-nitro-builder -f Dockerfile.nitro.builder . docker create --name uid2-nitro-builder uid2-nitro-builder docker cp uid2-nitro-builder:/build . docker rm uid2-nitro-builder mkdir -p build/conf touch build/build_artifacts.stamp - -.PHONY: install uninstall setup_nitro build_artifacts build_eif loki_override build/configs diff --git a/scripts/aws/pipeline/amazonlinux.Dockerfile b/scripts/aws/pipeline/amazonlinux.Dockerfile index d4372c3ee..e6d755bfd 100644 --- a/scripts/aws/pipeline/amazonlinux.Dockerfile +++ b/scripts/aws/pipeline/amazonlinux.Dockerfile @@ -4,9 +4,22 @@ FROM amazonlinux:2 RUN yum -y update # systemd is not a hard requirement for Amazon ECS Anywhere, but the installation script currently only supports systemd to run. # Amazon ECS Anywhere can be used without systemd, if you set up your nodes and register them into your ECS cluster **without** the installation script. -RUN yum -y install systemd vim-common +RUN yum -y groupinstall "Development Tools" +RUN yum -y install systemd vim-common wget git tar RUN yum clean all +RUN yum -y install cmake cmake3 +RUN alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \ +--slave /usr/local/bin/ctest ctest /usr/bin/ctest \ +--slave /usr/local/bin/cpack cpack /usr/bin/cpack \ +--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \ +--family cmake +RUN alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \ + --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \ + --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \ + --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \ + --family cmake + RUN cd /lib/systemd/system/sysinit.target.wants/; \ for i in *; do [ $i = systemd-tmpfiles-setup.service ] || rm -f $i; done RUN rm -f /lib/systemd/system/multi-user.target.wants/* \ diff --git a/scripts/aws/pipeline/aws_nitro_eif.sh b/scripts/aws/pipeline/aws_nitro_eif.sh index e08380364..beb08a528 100644 --- a/scripts/aws/pipeline/aws_nitro_eif.sh +++ b/scripts/aws/pipeline/aws_nitro_eif.sh @@ -2,14 +2,29 @@ set -x +cd / + +# Build dante +wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz +echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum +sha256sum --check dante_checksum +tar -xf dante-1.4.3.tar.gz +cd dante-1.4.3; ./configure; make; cd .. +cp dante-1.4.3/sockd/sockd ./ + +# Build vsockpx +git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git +mkdir uid2-aws-enclave-vsockproxy/build +cd uid2-aws-enclave-vsockproxy/build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo; make; cd ../.. +cp uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ./vsockpx + +# Build EIF dockerd & while (! docker stats --no-stream >/dev/null 2>&1); do # Docker takes a few seconds to initialize echo -n "." sleep 1 done - -docker load -i /$1.tar +docker load -i $1.tar nitro-cli build-enclave --docker-uri $1 --output-file $1.eif - nitro-cli describe-eif --eif-path $1.eif | jq -r '.Measurements.PCR0' | xxd -r -p | base64 > pcr0.txt From c95dc6b195d01d4e564a37ce6b7cc9952097cafc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 26 Feb 2024 15:58:44 +1100 Subject: [PATCH 0137/1116] Updated logging of OptOutClient --- conf/local-e2e-docker-public-config.json | 2 +- pom.xml | 2 +- .../java/com/uid2/operator/store/OptOutCloudStorage.java | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index fd0146fe5..b3157b064 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -27,7 +27,7 @@ "validate_service_links": true, "optout_s3_bucket": "test-optout-bucket", "optout_s3_folder": "optout-v2/", - "optout_metadata_path": "http://optout:8081/optout/refresh", + "optout_metadata_path": "/optout/refresh", "optout_api_uri": "http://optout:8081/optout/replicate", "optout_delta_rotate_interval": 60, "cloud_refresh_interval": 30 diff --git a/pom.xml b/pom.xml index d8e45df87..4d95f7d2d 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.2.0-41efc58fbf + 7.2.4-SNAPSHOT ${project.version} diff --git a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java index 3e1da17a6..d9b50f64e 100644 --- a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java +++ b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java @@ -36,14 +36,15 @@ protected List extractListFromMetadata() throws CloudStorageException { try (InputStream input = this.uidOptOutClient.download(metadataPath)) { String jsonString = Utils.readToEnd(input); if (jsonString != null && !jsonString.isEmpty()) { - OptOutMetadata m = OptOutMetadata.fromJsonString(Utils.readToEnd(input)); + OptOutMetadata m = OptOutMetadata.fromJsonString(jsonString); return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); } else { LOGGER.warn("Empty string returned from UidOptOutClient. Unable to read OptOut metadata"); return new ArrayList(); } } catch (IOException e) { - throw new CloudStorageException("extractListFromMetadata error" + e.getMessage(), e); + // Intentionally not logging the exception as it may contain sensitive URLs + throw new CloudStorageException("extractListFromMetadata error"); } } } From bcd74aa24cd2aea5269676eb609aa34e9568fdca Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 26 Feb 2024 16:19:01 +1100 Subject: [PATCH 0138/1116] Reverting cloud formation template --- e2e/ngrok.yml | 12 ------------ scripts/aws/UID_CloudFormation.template.yml | 3 ++- src/main/java/com/uid2/operator/Main.java | 18 +++++++++--------- .../operator/store/CloudSyncOptOutStore.java | 1 - 4 files changed, 11 insertions(+), 23 deletions(-) delete mode 100644 e2e/ngrok.yml diff --git a/e2e/ngrok.yml b/e2e/ngrok.yml deleted file mode 100644 index 081d3fdd8..000000000 --- a/e2e/ngrok.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: "2" -authtoken: 20IKxrKo9AT4GNovcz2Z10v4k2c_7aYZHCXL2puu8sBdefhh1 -tunnels: - localstack: - addr: 5001 - proto: http - optout: - addr: 8081 - proto: http - core: - addr: 8088 - proto: http diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index 4fc34159a..5c43450fb 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -31,6 +31,7 @@ Parameters: - m5a.4xlarge - m5n.2xlarge - m5n.4xlarge + ConstraintDescription: must be a valid EC2 instance type. RootVolumeSize: Description: Instance root volume size Type: Number @@ -102,7 +103,7 @@ Metadata: Mappings: RegionMap: us-east-1: - AMI: ami-069965aca2f4bb943 + AMI: ami-xxxxxxxxxxxxxxxxx us-east-2: AMI: ami-xxxxxxxxxxxxxxxxx us-west-1: diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index d10fda7a9..5bbd874cd 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -452,31 +452,31 @@ public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticC } private Map.Entry createUidClients(Vertx vertx, String attestationUrl, String clientApiToken, Handler> responseWatcher) throws Exception { - AttestationTokenRetriever attestationTokenRetriever = getAttestationTokenRetriever(vertx, attestationUrl, clientApiToken, responseWatcher); - UidCoreClient coreClient = new UidCoreClient(clientApiToken, CloudUtils.defaultProxy, attestationTokenRetriever); - UidOptOutClient optOutClient = new UidOptOutClient(clientApiToken, CloudUtils.defaultProxy, attestationTokenRetriever); + AttestationResponseHandler attestationResponseHandler = getAttestationTokenRetriever(vertx, attestationUrl, clientApiToken, responseWatcher); + UidCoreClient coreClient = new UidCoreClient(clientApiToken, CloudUtils.defaultProxy, attestationResponseHandler); + UidOptOutClient optOutClient = new UidOptOutClient(clientApiToken, CloudUtils.defaultProxy, attestationResponseHandler); return new AbstractMap.SimpleEntry<>(coreClient, optOutClient); } - private AttestationTokenRetriever getAttestationTokenRetriever(Vertx vertx, String attestationUrl, String clientApiToken, Handler> responseWatcher) throws Exception { + private AttestationResponseHandler getAttestationTokenRetriever(Vertx vertx, String attestationUrl, String clientApiToken, Handler> responseWatcher) throws Exception { String enclavePlatform = this.config.getString("enclave_platform"); if (Strings.isNullOrEmpty(enclavePlatform)) { - return new AttestationTokenRetriever(vertx, attestationUrl, clientApiToken, this.appVersion, new NoAttestationProvider(), responseWatcher, CloudUtils.defaultProxy); + return new AttestationResponseHandler(vertx, attestationUrl, clientApiToken, this.appVersion, new NoAttestationProvider(), responseWatcher, CloudUtils.defaultProxy); } switch (enclavePlatform) { case "aws-nitro": LOGGER.info("creating uid core client with aws attestation protocol"); - return new AttestationTokenRetriever(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getNitroAttestation(), responseWatcher, CloudUtils.defaultProxy); + return new AttestationResponseHandler(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getNitroAttestation(), responseWatcher, CloudUtils.defaultProxy); case "gcp-vmid": LOGGER.info("creating uid core client with gcp vmid attestation protocol"); - return new AttestationTokenRetriever(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getGcpVmidAttestation(), responseWatcher, CloudUtils.defaultProxy); + return new AttestationResponseHandler(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getGcpVmidAttestation(), responseWatcher, CloudUtils.defaultProxy); case "gcp-oidc": LOGGER.info("creating uid core client with gcp oidc attestation protocol"); - return new AttestationTokenRetriever(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getGcpOidcAttestation(), responseWatcher, CloudUtils.defaultProxy); + return new AttestationResponseHandler(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getGcpOidcAttestation(), responseWatcher, CloudUtils.defaultProxy); case "azure-cc": LOGGER.info("creating uid core client with azure cc attestation protocol"); String maaServerBaseUrl = this.config.getString(Const.Config.MaaServerBaseUrlProp, "https://sharedeus.eus.attest.azure.net"); - return new AttestationTokenRetriever(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getAzureCCAttestation(maaServerBaseUrl), responseWatcher, CloudUtils.defaultProxy); + return new AttestationResponseHandler(vertx, attestationUrl, clientApiToken, this.appVersion, AttestationFactory.getAzureCCAttestation(maaServerBaseUrl), responseWatcher, CloudUtils.defaultProxy); default: throw new IllegalArgumentException(String.format("enclave_platform is providing the wrong value: %s", enclavePlatform)); } diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 1df9c917b..a7239f65d 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -83,7 +83,6 @@ public void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, return; } - LOGGER.debug("CloudSyncOptOutStore calling endpoint: {}", remoteApiHost); this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath). addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.id)) .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) From c3335eeac31e159b3fa5703ad35a5d7510613a60 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 26 Feb 2024 14:37:10 +0800 Subject: [PATCH 0139/1116] Added check to see if Docker is already running in amazonlinux --- .github/actions/build_aws_eif/action.yaml | 8 ++++++++ scripts/aws/pipeline/amazonlinux.Dockerfile | 12 ++++++++++++ scripts/aws/pipeline/aws_nitro_eif.sh | 16 ---------------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 837bb760f..07a434b4f 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -13,6 +13,14 @@ runs: using: "composite" steps: + - name: Run amazonlinux Docker image + shell: bash + run: | + docker stop $(docker ps -a -q) + docker system prune -f + docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . + docker run -d --privileged --name amazonlinux amazonlinux:latest + - name: Create build folder id: buildFolder shell: bash diff --git a/scripts/aws/pipeline/amazonlinux.Dockerfile b/scripts/aws/pipeline/amazonlinux.Dockerfile index e6d755bfd..90f6d0505 100644 --- a/scripts/aws/pipeline/amazonlinux.Dockerfile +++ b/scripts/aws/pipeline/amazonlinux.Dockerfile @@ -35,6 +35,18 @@ RUN yum -y install aws-nitro-enclaves-cli-devel RUN systemctl enable docker +RUN wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz \ + && echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum \ + && sha256sum --check dante_checksum \ + && tar -xf dante-1.4.3.tar.gz \ + && cd dante-1.4.3; ./configure; make; cd .. \ + && cp dante-1.4.3/sockd/sockd ./ + +RUN git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git \ + && mkdir uid2-aws-enclave-vsockproxy/build \ + && cd uid2-aws-enclave-vsockproxy/build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo; make; cd ../.. \ + && cp uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ./vsockpx + COPY ./scripts/aws/pipeline/aws_nitro_eif.sh /aws_nitro_eif.sh CMD ["/usr/sbin/init"] diff --git a/scripts/aws/pipeline/aws_nitro_eif.sh b/scripts/aws/pipeline/aws_nitro_eif.sh index beb08a528..2d8f0216b 100644 --- a/scripts/aws/pipeline/aws_nitro_eif.sh +++ b/scripts/aws/pipeline/aws_nitro_eif.sh @@ -2,22 +2,6 @@ set -x -cd / - -# Build dante -wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz -echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum -sha256sum --check dante_checksum -tar -xf dante-1.4.3.tar.gz -cd dante-1.4.3; ./configure; make; cd .. -cp dante-1.4.3/sockd/sockd ./ - -# Build vsockpx -git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git -mkdir uid2-aws-enclave-vsockproxy/build -cd uid2-aws-enclave-vsockproxy/build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo; make; cd ../.. -cp uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ./vsockpx - # Build EIF dockerd & while (! docker stats --no-stream >/dev/null 2>&1); do From b630fa6b0571a8e803940d89f85d282fe94153cb Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 27 Feb 2024 09:44:17 +1100 Subject: [PATCH 0140/1116] Added config for latest version of operator in Validator --- .gitignore | 1 - ...dator-latest-e2e-docker-public-config.json | 35 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 conf/validator-latest-e2e-docker-public-config.json diff --git a/.gitignore b/.gitignore index f3a05b4f1..f6eafd493 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ target/* .idea/* .idea/ dependencies/ -conf/*.json uid2-operator.iml build/** e2e-target diff --git a/conf/validator-latest-e2e-docker-public-config.json b/conf/validator-latest-e2e-docker-public-config.json new file mode 100644 index 000000000..87b042c7b --- /dev/null +++ b/conf/validator-latest-e2e-docker-public-config.json @@ -0,0 +1,35 @@ +{ + "service_instances": 1, + "storage_mock": false, + "enforce_https": false, + "core_attest_url": "http://core:8088/attest", + "core_api_token": "UID2-O-L-999-dp9Dt0.JVoGpynN4J8nMA7FxmzsavxJa8B9H74y9xdEE=", + "sites_metadata_path": "http://core:8088/sites/refresh", + "clients_metadata_path": "http://core:8088/clients/refresh", + "client_side_keypairs_metadata_path": "http://core:8088/client_side_keypairs/refresh", + "keys_metadata_path": "http://core:8088/key/refresh", + "keys_acl_metadata_path": "http://core:8088/key/acl/refresh", + "keysets_metadata_path": "http://core:8088/key/keyset/refresh", + "keyset_keys_metadata_path": "http://core:8088/key/keyset-keys/refresh", + "salts_metadata_path": "http://core:8088/salt/refresh", + "services_metadata_path": "http://core:8088/services/refresh", + "service_links_metadata_path": "http://core:8088/service_links/refresh", + "identity_token_expires_after_seconds": 3600, + "refresh_token_expires_after_seconds": 86400, + "refresh_identity_token_after_seconds": 900, + "advertising_token_v3": false, + "refresh_token_v3": true, + "identity_v3": false, + "identity_scope": "uid2", + "enable_v2_encryption": true, + "client_side_token_generate": true, + "client_side_token_generate_domain_name_check_enabled": true, + "key_sharing_endpoint_provide_site_domain_names": true, + "validate_service_links": true, + "optout_s3_bucket": "test-optout-bucket", + "optout_s3_folder": "optout-v2/", + "optout_metadata_path": "http://optout:8081/optout/refresh", + "optout_api_uri": "http://optout:8081/optout/replicate", + "optout_delta_rotate_interval": 60, + "cloud_refresh_interval": 30 +} From 94d7c892602c6ed613c810b77d3f745b25329793 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 27 Feb 2024 00:22:30 +0000 Subject: [PATCH 0141/1116] Released Patch version: 5.27.11-1e3563052b --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8e45df87..75f2cd5d7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.10-3f25586306 + 5.27.11-1e3563052b UTF-8 From 24a8414148b16b3f0d6ea7042db669b7383aa32d Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 27 Feb 2024 14:28:22 +0800 Subject: [PATCH 0142/1116] Updated VERSION and EIF filenames --- .github/actions/build_aws_eif/action.yaml | 4 ++-- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 07a434b4f..2deced658 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -60,9 +60,9 @@ runs: cp ./scripts/aws/proxies.host.yaml ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/VERSION docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ - docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/ + docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/uid2operator.eif docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 864a613c4..56ba14dde 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -33,7 +33,7 @@ on: env: ENCLAVE_PROTOCOL: aws-nitro - ARTIFACTS_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts + ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts jobs: buildImage: @@ -124,15 +124,15 @@ jobs: uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif with: identity_scope: uid2 - artifacts_base_output_dir: ${{ env.ARTIFACTS_OUTPUT_DIR }} + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - name: Build EUID AWS EIF uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif with: identity_scope: euid - artifacts_base_output_dir: ${{ env.ARTIFACTS_OUTPUT_DIR }} + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - uses: actions/upload-artifact@v3 with: name: aws-nitro-deployment-files - path: ${{ env.ARTIFACTS_OUTPUT_DIR }} + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} From ac365b36d1d0c914c425f920bd4a062dee55ca0b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 28 Feb 2024 12:54:13 +1100 Subject: [PATCH 0143/1116] Updated version of shared --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4d95f7d2d..b47334061 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.2.4-SNAPSHOT + 7.3.0-0c9c5b24fe ${project.version} From d3eb92ef16be251ff65593cb06378ac3ccdc4565 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 28 Feb 2024 11:03:47 +0800 Subject: [PATCH 0144/1116] Uncommented code from testing --- .github/workflows/publish-all-operators.yaml | 2 +- .../publish-aws-nitro-enclave-docker.yaml | 50 +++++++++---------- .../publish-azure-cc-enclave-docker.yaml | 2 +- .../publish-gcp-oidc-enclave-docker.yaml | 2 +- .../publish-public-operator-docker-image.yaml | 2 +- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index b3ea593d4..9fdb18493 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -5,7 +5,7 @@ on: inputs: release_type: type: choice - description: 'The type of release' + description: The type of release options: - Major - Minor diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 56ba14dde..58a338287 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -5,7 +5,7 @@ on: inputs: release_type: type: choice - description: 'The type of release' + description: The type of release options: - Major - Minor @@ -42,11 +42,11 @@ jobs: outputs: pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: -# - name: Check branch and release type -# id: checkRelease -# uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 -# with: -# release_type: ${{ inputs.release_type }} + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + with: + release_type: ${{ inputs.release_type }} - name: Free up space run: | @@ -59,7 +59,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} -# IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - name: Checkout full history on Main uses: actions/checkout@v4 @@ -96,24 +96,24 @@ jobs: echo "Version number updated from $current_version to $new_version" echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT -# - name: Commit pom.xml and version.json -# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} -# uses: EndBug/add-and-commit@v9 -# with: -# add: 'pom.xml version.json' -# author_name: Release Workflow -# author_email: unifiedid-admin+release@thetradedesk.com -# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' -# -# - name: Commit pom.xml, version.json and set tag -# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} -# uses: EndBug/add-and-commit@v9 -# with: -# add: 'pom.xml version.json' -# author_name: Release Workflow -# author_email: unifiedid-admin+release@thetradedesk.com -# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' -# tag: v${{ steps.version.outputs.new_version }} + - name: Commit pom.xml and version.json + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + + - name: Commit pom.xml, version.json and set tag + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + tag: v${{ steps.version.outputs.new_version }} - name: Run amazonlinux Docker image run: | diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index f719eda24..d9b6f3e32 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -5,7 +5,7 @@ on: inputs: release_type: type: choice - description: 'The type of release' + description: The type of release options: - Major - Minor diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index b08bd2930..c3b600ead 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -5,7 +5,7 @@ on: inputs: release_type: type: choice - description: 'The type of release' + description: The type of release options: - Major - Minor diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 0b231bfbc..28b93c21f 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -5,7 +5,7 @@ on: inputs: release_type: type: choice - description: 'The type of release' + description: The type of release options: - Major - Minor From ec695dea53d8e456597e0a3c2bb29cd59b72d365 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 28 Feb 2024 14:58:45 +1100 Subject: [PATCH 0145/1116] UID2-2558 Use commit_pr_and_merge workflow (#364) * Use commit_pr_and_merge workflow * Remove non release check --- .github/workflows/publish-all-operators.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index f452d431b..50bbd4862 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -27,7 +27,7 @@ jobs: GITHUB_CONTEXT: ${{ toJson(github) }} - name: Check branch and release type - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2 with: release_type: ${{ inputs.release_type }} @@ -37,7 +37,7 @@ jobs: fetch-depth: 0 - name: Scan vulnerabilities - uses: IABTechLab/uid2-shared-actions/actions/vulnerability_scan_filesystem@v2.4.0 + uses: IABTechLab/uid2-shared-actions/actions/vulnerability_scan_filesystem@v2 with: scan_severity: HIGH,CRITICAL failure_severity: CRITICAL @@ -56,14 +56,12 @@ jobs: sed -i "s/$current_version/$new_version/g" pom.xml echo "Version number updated from $current_version to $new_version" - - name: Commit pom.xml and version.json - uses: EndBug/add-and-commit@v9 + - name: Commit pom.xml, version.json and set tag + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} + tag: v${{ steps.version.outputs.new_version }} buildPublic: name: Public Operator From 4010ffb177ed66cf74336178a6edc73ea56cc3ab Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 28 Feb 2024 03:59:41 +0000 Subject: [PATCH 0146/1116] [CI Pipeline] Released Patch version: 5.27.19-ec695dea53 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 79d8a53cc..088cf398a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.11-1e3563052b + 5.27.19-ec695dea53 UTF-8 From af32170d3038d98b6aa954fb67ccd9dbcc74feb4 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 28 Feb 2024 15:08:57 +1100 Subject: [PATCH 0147/1116] UID2-2861 Fix-github-warnings (#362) * Use kcc-UID2-2861-fix-github-warnings for testing * Update actions/download-artifact@v3 to v4 * Revert kcc-UID2-2861-fix-github-warnings to v2 --- .github/workflows/publish-all-operators.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 50bbd4862..0b6ea6d80 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -96,19 +96,19 @@ jobs: needs: [start, buildPublic, buildGCP, buildAzure] steps: - name: Download public artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: image-details path: ./artifacts/public_operator - name: Download GCP artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: gcp-oidc-deployment-files path: ./artifacts/gcp_oidc_operator - name: Download Azure artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: azure-cc-deployment-files path: ./artifacts/azure_cc_operator From 0bf11d2bbac005b6e5dadc9e62bb0c5aab98d163 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 28 Feb 2024 06:08:52 +0000 Subject: [PATCH 0148/1116] [CI Pipeline] Released Patch version: 5.27.22-af32170d30 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 088cf398a..72b416038 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.19-ec695dea53 + 5.27.22-af32170d30 UTF-8 From bfbffd6d079193710014462a83cbbe6e15639539 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 28 Feb 2024 17:26:50 +1100 Subject: [PATCH 0149/1116] UID2-2861 fix GitHub warnings (#367) * Use kcc-UID2-2861-fix-github-warnings for testing * Revert kcc-UID2-2861-fix-github-warnings to v2 * Update versions to get rid of github warnings --- .github/workflows/e2e-azure-cc-enclave.yaml | 2 +- .github/workflows/e2e-gcp-oidc-enclave.yaml | 2 +- .github/workflows/publish-all-operators.yaml | 2 +- .../publish-aws-nitro-enclave-docker.yaml | 2 +- .../publish-azure-cc-enclave-docker.yaml | 30 ++++++++----------- .../publish-gcp-oidc-enclave-docker.yaml | 26 +++++++--------- .../publish-public-operator-docker-image.yaml | 2 +- 7 files changed, 29 insertions(+), 37 deletions(-) diff --git a/.github/workflows/e2e-azure-cc-enclave.yaml b/.github/workflows/e2e-azure-cc-enclave.yaml index 0cb311480..02fb8734c 100644 --- a/.github/workflows/e2e-azure-cc-enclave.yaml +++ b/.github/workflows/e2e-azure-cc-enclave.yaml @@ -50,7 +50,7 @@ jobs: cd ./e2e && bash ./setup_ngrok.sh - name: Log in to the Docker container registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} diff --git a/.github/workflows/e2e-gcp-oidc-enclave.yaml b/.github/workflows/e2e-gcp-oidc-enclave.yaml index 307e4a588..a8479cb3c 100644 --- a/.github/workflows/e2e-gcp-oidc-enclave.yaml +++ b/.github/workflows/e2e-gcp-oidc-enclave.yaml @@ -58,7 +58,7 @@ jobs: cd ./e2e && bash ./prepare_gcp_enclave_metadata.sh - name: Log in to the Docker container registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 0b6ea6d80..84a3938ef 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -122,7 +122,7 @@ jobs: azure-cc-deployment-files - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: uid2-operator-release-${{ needs.start.outputs.new_version }} path: ./artifacts/ diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index e2649537a..97b50230b 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -33,6 +33,6 @@ jobs: steps: - name: Check branch and release type id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2 with: release_type: ${{ inputs.release_type }} diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 05d0f61e9..777e2eb46 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -54,7 +54,7 @@ jobs: steps: - name: Check branch and release type id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2 with: release_type: ${{ inputs.release_type }} @@ -65,10 +65,10 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} - IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + IS_RELEASE: ${{ steps.checkRelease.outputs.is_release }} - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' @@ -89,7 +89,7 @@ jobs: fetch-depth: 0 - name: Restore timestamps - uses: thetradedesk/git-restore-mtime-action@v1.2 + uses: thetradedesk/git-restore-mtime-action@v1.3 - name: Set version number id: version @@ -117,23 +117,19 @@ jobs: cp -r target ${{ env.DOCKER_CONTEXT_PATH }}/ - name: Commit pom.xml and version.json - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} - uses: EndBug/add-and-commit@v9 + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release != 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - name: Commit pom.xml, version.json and set tag - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} - uses: EndBug/add-and-commit@v9 + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} + tag: v${{ steps.version.outputs.new_version }} - name: Log in to the Docker container registry uses: docker/login-action@v3 @@ -208,20 +204,20 @@ jobs: bash ./scripts/azure-cc/deployment/generate-deployment-artifacts.sh - name: Archive deployment artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: azure-cc-deployment-files path: | ${{ env.ARTIFACTS_OUTPUT_DIR }} - name: Generate release archive - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - name: Build Changelog id: github_release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v3 with: configurationJson: | @@ -233,7 +229,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create Release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v1 with: name: ${{ steps.version.outputs.new_version }} diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 5c9da76d2..a965d9f82 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -67,10 +67,10 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} - IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + IS_RELEASE: ${{ steps.checkRelease.outputs.is_release }} - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' @@ -91,7 +91,7 @@ jobs: fetch-depth: 0 - name: Restore timestamps - uses: thetradedesk/git-restore-mtime-action@v1.2 + uses: thetradedesk/git-restore-mtime-action@v1.3 - name: Set version number id: version @@ -119,21 +119,17 @@ jobs: cp -r target ${{ env.DOCKER_CONTEXT_PATH }}/ - name: Commit pom.xml and version.json - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} - uses: EndBug/add-and-commit@v9 + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release != 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - name: Commit pom.xml, version.json and set tag - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} - uses: EndBug/add-and-commit@v9 + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} @@ -245,20 +241,20 @@ jobs: bash ./scripts/gcp-oidc/generate-deployment-artifacts.sh - name: Archive deployment artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gcp-oidc-deployment-files path: | ${{ env.ARTIFACTS_OUTPUT_DIR }} - name: Generate release archive - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - name: Build Changelog id: github_release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v3 with: configurationJson: | @@ -270,7 +266,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create Release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v1 with: name: ${{ steps.version.outputs.new_version }} diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 839451afc..741197d59 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -65,7 +65,7 @@ jobs: echo $IMAGE > image-details/image.json - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: image-details path: image-details/ From 7585cb1f2b73db957f09026fe82b0d3e47949d58 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 28 Feb 2024 06:27:52 +0000 Subject: [PATCH 0150/1116] [CI Pipeline] Released Patch version: 5.27.25-bfbffd6d07 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 72b416038..044131a2b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.22-af32170d30 + 5.27.25-bfbffd6d07 UTF-8 From ac1e0e92f61782cebdde2cc852a8671767dd6113 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 28 Feb 2024 17:36:36 +1100 Subject: [PATCH 0151/1116] UID2-2861 fix GitHub warnings (#369) * Use kcc-UID2-2861-fix-github-warnings for testing * Revert kcc-UID2-2861-fix-github-warnings to v2 * Update action version --- .github/workflows/publish-all-operators.yaml | 2 +- .github/workflows/publish-azure-cc-enclave-docker.yaml | 4 ++-- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 84a3938ef..d7b5b8a94 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -142,7 +142,7 @@ jobs: - name: Build changelog id: changelog - uses: mikepenz/release-changelog-builder-action@v3 + uses: mikepenz/release-changelog-builder-action@v4 with: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 777e2eb46..4bb41214c 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -170,7 +170,7 @@ jobs: hide-progress: true - name: Upload Trivy scan report to GitHub Security tab - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif' @@ -218,7 +218,7 @@ jobs: - name: Build Changelog id: github_release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} - uses: mikepenz/release-changelog-builder-action@v3 + uses: mikepenz/release-changelog-builder-action@v4 with: configurationJson: | { diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index a965d9f82..6168e67b0 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -206,7 +206,7 @@ jobs: hide-progress: true - name: Upload Trivy scan report to GitHub Security tab - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif' @@ -255,7 +255,7 @@ jobs: - name: Build Changelog id: github_release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} - uses: mikepenz/release-changelog-builder-action@v3 + uses: mikepenz/release-changelog-builder-action@v4 with: configurationJson: | { From db858851bb874834befd3a53a15d330492ab4662 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 28 Feb 2024 06:37:33 +0000 Subject: [PATCH 0152/1116] [CI Pipeline] Released Patch version: 5.27.28-ac1e0e92f6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 044131a2b..f5ded9788 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.25-bfbffd6d07 + 5.27.28-ac1e0e92f6 UTF-8 From 89a64a429d6f6ec957e572002653b076dd4f9c60 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 28 Feb 2024 06:45:01 +0000 Subject: [PATCH 0153/1116] [CI Pipeline] Released Patch version: 5.27.30-2ceb45287e --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f5ded9788..95ee5941d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.28-ac1e0e92f6 + 5.27.30-2ceb45287e UTF-8 From cf0479a9997b63f6b6efd51c7af7784991933cba Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 28 Feb 2024 17:57:14 +1100 Subject: [PATCH 0154/1116] Added max_sharing_lifetime_seconds and identity_scope fields in key/sharing endpoint --- src/main/java/com/uid2/operator/Const.java | 1 + src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/com/uid2/operator/Const.java b/src/main/java/com/uid2/operator/Const.java index 3cd1e8409..fda0cf9e6 100644 --- a/src/main/java/com/uid2/operator/Const.java +++ b/src/main/java/com/uid2/operator/Const.java @@ -13,6 +13,7 @@ public class Config extends com.uid2.shared.Const.Config { public static final String FailureShutdownWaitHoursProp = "failure_shutdown_wait_hours"; public static final String AllowLegacyAPIProp = "allow_legacy_api"; public static final String SharingTokenExpiryProp = "sharing_token_expiry_seconds"; + public static final String MaxSharingLifetimeProp = "max_sharing_lifetime_seconds"; public static final String EnableClientSideTokenGenerate = "client_side_token_generate"; public static final String ValidateServiceLinks = "validate_service_links"; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index b5c2a4760..199a74e9b 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -535,6 +535,9 @@ public void handleKeysSharing(RoutingContext rc) { LOGGER.warn(String.format("Cannot get a default keyset with SITE ID %d. Caller will not be able to encrypt tokens..", clientKey.getSiteId())); } resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); + resp.put("max_sharing_lifetime_seconds", config.getString(Const.Config.SharingTokenExpiryProp, getSharingTokenExpirySeconds())); + resp.put("identity_scope", this.identityScope.name()); + // include 'keyset_id' field, if: // (a) a key belongs to caller's enabled site From 6bcdb3bf8e9faa638455e2ced8ed62569e4f4ce8 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 28 Feb 2024 18:21:30 +1100 Subject: [PATCH 0155/1116] Added max_sharing_lifetime_seconds and identity_scope fields in key/sharing endpoint --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 4 +++- .../com/uid2/operator/ExtendedUIDOperatorVerticle.java | 4 ++++ .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 199a74e9b..fec8b724b 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -106,6 +106,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); + protected int maxSharingLifetimeSeconds; protected boolean keySharingEndpointProvideSiteDomainNames; public UIDOperatorVerticle(JsonObject config, @@ -144,6 +145,7 @@ public UIDOperatorVerticle(JsonObject config, this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; + this.maxSharingLifetimeSeconds = config.getInteger(Const.Config.MaxSharingLifetimeProp, config.getInteger(Const.Config.SharingTokenExpiryProp)); } @Override @@ -535,7 +537,7 @@ public void handleKeysSharing(RoutingContext rc) { LOGGER.warn(String.format("Cannot get a default keyset with SITE ID %d. Caller will not be able to encrypt tokens..", clientKey.getSiteId())); } resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); - resp.put("max_sharing_lifetime_seconds", config.getString(Const.Config.SharingTokenExpiryProp, getSharingTokenExpirySeconds())); + resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); resp.put("identity_scope", this.identityScope.name()); diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index 38f5eeb7c..a6bb2c981 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -36,4 +36,8 @@ public void setKeySharingEndpointProvideSiteDomainNames(boolean enable) { this.keySharingEndpointProvideSiteDomainNames = enable; } + public void setMaxSharingLifetimeSeconds(int maxSharingLifetimeSeconds) { + this.maxSharingLifetimeSeconds = maxSharingLifetimeSeconds; + } + } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b73531183..fa4047eed 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -105,6 +105,7 @@ public class UIDOperatorVerticleTest { private SimpleMeterRegistry registry; private ExtendedUIDOperatorVerticle uidOperatorVerticle; + private JsonObject config; @BeforeEach public void deployVerticle(Vertx vertx, VertxTestContext testContext, TestInfo testInfo) { @@ -114,7 +115,7 @@ public void deployVerticle(Vertx vertx, VertxTestContext testContext, TestInfo t when(this.secureLinkValidatorService.validateRequest(any(RoutingContext.class), any(JsonObject.class), any(Role.class))).thenReturn(true); - JsonObject config = new JsonObject(); + config = new JsonObject(); setupConfig(config); if(testInfo.getDisplayName().equals("cstgNoPhoneSupport(Vertx, VertxTestContext)")) { config.put("enable_phone_support", false); @@ -3964,6 +3965,10 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext) { assertEquals(clientSiteId, respJson.getJsonObject("body").getInteger("caller_site_id")); assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, respJson.getJsonObject("body").getInteger("master_keyset_id")); assertEquals(4, respJson.getJsonObject("body").getInteger("default_keyset_id")); + + assertEquals(this.config.getInteger(Const.Config.SharingTokenExpiryProp), respJson.getJsonObject("body").getInteger("max_sharing_lifetime_seconds")); + assertEquals(getIdentityScope().toString(), respJson.getJsonObject("body").getString("identity_scope")); + checkEncryptionKeysSharing(respJson, clientSiteId, expectedKeys); HashMap> expectedSites = setupExpectation(101, 104); From ac8e72ba18e196d215cd9d7990b9a71fdbae6998 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 28 Feb 2024 18:29:10 +1100 Subject: [PATCH 0156/1116] Added max_sharing_lifetime_seconds and identity_scope fields in key/sharing endpoint --- .../operator/UIDOperatorVerticleTest.java | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index fa4047eed..cc724a0d6 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -3924,14 +3924,24 @@ void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, Vertx vertx, Ver } @Test - // Tests: - // SHARER has access to a keyset that has the same site_id as ID_READER's - direct access - // SHARER has access to a keyset with allowed_sites that includes us - access through sharing - // SHARER has no access to a keyset that is disabled - direct reject - // SHARER has no access to a keyset with a missing allowed_sites - reject by sharing - // SHARER has no access to a keyset with an empty allowed_sites - reject by sharing - // SHARER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext) { + void keySharingKeysets_SHARER_CustomMaxSharingLifetimeSeconds(Vertx vertx, VertxTestContext testContext) { + this.uidOperatorVerticle.setMaxSharingLifetimeSeconds(999999); + keySharingKeysets_SHARER(vertx, testContext, 999999); + } + + @Test + void keySharingKeysets_SHARER_defaultMaxSharingLifetimeSeconds(Vertx vertx, VertxTestContext testContext) { + keySharingKeysets_SHARER(vertx, testContext, this.config.getInteger(Const.Config.SharingTokenExpiryProp)); + } + + // Tests: + // SHARER has access to a keyset that has the same site_id as ID_READER's - direct access + // SHARER has access to a keyset with allowed_sites that includes us - access through sharing + // SHARER has no access to a keyset that is disabled - direct reject + // SHARER has no access to a keyset with a missing allowed_sites - reject by sharing + // SHARER has no access to a keyset with an empty allowed_sites - reject by sharing + // SHARER has no access to a keyset with an allowed_sites for other sites - reject by sharing + void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int expectedMaxSharingLifetimeSeconds) { String apiVersion = "v2"; int clientSiteId = 101; fakeAuth(clientSiteId, Role.SHARER); @@ -3966,7 +3976,7 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext) { assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, respJson.getJsonObject("body").getInteger("master_keyset_id")); assertEquals(4, respJson.getJsonObject("body").getInteger("default_keyset_id")); - assertEquals(this.config.getInteger(Const.Config.SharingTokenExpiryProp), respJson.getJsonObject("body").getInteger("max_sharing_lifetime_seconds")); + assertEquals(expectedMaxSharingLifetimeSeconds, respJson.getJsonObject("body").getInteger("max_sharing_lifetime_seconds")); assertEquals(getIdentityScope().toString(), respJson.getJsonObject("body").getString("identity_scope")); checkEncryptionKeysSharing(respJson, clientSiteId, expectedKeys); From 4d6e5c36d62c2b79c0a3369b5da3c7602930c641 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 28 Feb 2024 18:41:35 +1100 Subject: [PATCH 0157/1116] Added max_sharing_lifetime_seconds and identity_scope fields in key/sharing endpoint --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index cc724a0d6..7fffc0b90 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -3975,7 +3975,8 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int exp assertEquals(clientSiteId, respJson.getJsonObject("body").getInteger("caller_site_id")); assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, respJson.getJsonObject("body").getInteger("master_keyset_id")); assertEquals(4, respJson.getJsonObject("body").getInteger("default_keyset_id")); - + + assertEquals(config.getInteger(Const.Config.SharingTokenExpiryProp), Integer.parseInt(respJson.getJsonObject("body").getString("token_expiry_seconds"))); assertEquals(expectedMaxSharingLifetimeSeconds, respJson.getJsonObject("body").getInteger("max_sharing_lifetime_seconds")); assertEquals(getIdentityScope().toString(), respJson.getJsonObject("body").getString("identity_scope")); From b7e220aefcf543f0f1aca54c76e7e1880129e2df Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 28 Feb 2024 17:17:00 +0800 Subject: [PATCH 0158/1116] Updated branch to main for action references --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 58a338287..7efd54315 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -121,13 +121,13 @@ jobs: docker run -d --privileged --name amazonlinux amazonlinux:latest - name: Build UID2 AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - name: Build EUID AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2770-aws-eif + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} From 9686480f5fad859113b07ba831253be68f7c8488 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Thu, 29 Feb 2024 11:44:37 +1100 Subject: [PATCH 0159/1116] added a warning on token_expiry_seconds string output --- src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index fec8b724b..9dcdcf931 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -536,6 +536,9 @@ public void handleKeysSharing(RoutingContext rc) { } else if (roleAuthorize.hasRole(Role.SHARER)) { LOGGER.warn(String.format("Cannot get a default keyset with SITE ID %d. Caller will not be able to encrypt tokens..", clientKey.getSiteId())); } + // this is written out as a String, i.e. in the JSON response of key/sharing endpoint, it would show: + // "token_expiry_seconds" : "2592000" + // it should be an integer instead, but we can't change it until we confirm that the oldest version of each of our SDKs support this resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); resp.put("identity_scope", this.identityScope.name()); From b9bbe17f32e03a0653d0edc5e91a197ee952cf02 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 1 Mar 2024 10:24:56 +1100 Subject: [PATCH 0160/1116] Only return max_sharing_lifetime_seconds for role SHARER --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 9dcdcf931..951242092 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -540,7 +540,11 @@ public void handleKeysSharing(RoutingContext rc) { // "token_expiry_seconds" : "2592000" // it should be an integer instead, but we can't change it until we confirm that the oldest version of each of our SDKs support this resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); - resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); + + if (roleAuthorize.hasRole(Role.SHARER)) { + resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); + } + resp.put("identity_scope", this.identityScope.name()); From 46858a307f33c4bb2f33decf79d14a94c5f6bb9b Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Fri, 1 Mar 2024 10:26:10 +1100 Subject: [PATCH 0161/1116] Rename feature branch input helper text (#373) --- .../workflows/run-e2e-tests-on-operator.yaml | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index cca20f887..f72e680a2 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -13,35 +13,35 @@ on: operator_image_version: description: The pipeline will run the E2E test with this operator image version type: string - default: 'latest' + default: latest core_image_version: description: The pipeline will run the E2E test with this core image version type: string - default: 'latest' + default: latest optout_image_version: description: The pipeline will run the E2E test with this optout image version type: string - default: 'latest' + default: latest e2e_image_version: description: The pipeline will run the E2E test with this e2e image version type: string - default: 'latest' + default: latest core_branch: - description: 'The branch of UID2-core to test on' + description: 'Core: use this branch for Core config to test with' type: string - default: 'main' + default: main optout_branch: - description: 'The branch of UID2-optout to test on' + description: 'Optout: use this branch for Optout config to test with' type: string - default: 'main' + default: main admin_branch: - description: 'The branch of UID2-admin to test on' + description: 'Admin: use this branch for Admin config to test with' type: string - default: 'main' + default: main operator_branch: - description: 'The branch of UID2-operator to test on' + description: 'Operator: use this branch for Operator config to test with' type: string - default: 'main' + default: main workflow_call: inputs: operator_type: @@ -51,35 +51,35 @@ on: operator_image_version: description: The pipeline will run the E2E test with this operator image version type: string - default: 'latest' + default: latest core_image_version: description: The pipeline will run the E2E test with this core image version type: string - default: 'latest' + default: latest optout_image_version: description: The pipeline will run the E2E test with this optout image version type: string - default: 'latest' + default: latest e2e_image_version: description: The pipeline will run the E2E test with this e2e image version type: string - default: 'latest' + default: latest core_branch: - description: 'The branch of UID2-core to test on' + description: 'Core: use this branch for Core config to test with' type: string - default: 'main' + default: main optout_branch: - description: 'The branch of UID2-optout to test on' + description: 'Optout: use this branch for Optout config to test with' type: string - default: 'main' + default: main admin_branch: - description: 'The branch of UID2-admin to test on' + description: 'Admin: use this branch for Admin config to test with' type: string - default: 'main' + default: main operator_branch: - description: 'The branch of UID2-operator to test on' + description: 'Operator: use this branch for Operator config to test with' type: string - default: 'main' + default: main jobs: e2e-test: From a21c479c96833fb41d0587b6df074db55c55ae72 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 1 Mar 2024 10:57:46 +1100 Subject: [PATCH 0162/1116] Extract method getMissingAclMode --- .../uid2/operator/vertx/UIDOperatorVerticle.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 951242092..ce46068aa 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -521,12 +521,9 @@ public void handleKeysSharing(RoutingContext rc) { // defaultKeysetId allows calling sdk.Encrypt(rawUid) without specifying the keysetId Keyset defaultKeyset = keyManagerSnapshot.getDefaultKeyset(); - MissingAclMode mode = MissingAclMode.DENY_ALL; // This will break if another Type is added to this map IRoleAuthorizable roleAuthorize = (IRoleAuthorizable) rc.data().get(API_CLIENT_PROP); - if (roleAuthorize.hasRole(Role.ID_READER)) { - mode = MissingAclMode.ALLOW_ALL; - } + final MissingAclMode mode = getMissingAclMode(clientKey); final JsonObject resp = new JsonObject(); resp.put("caller_site_id", clientKey.getSiteId()); @@ -1723,11 +1720,12 @@ private JsonObject toJsonV1(IdentityTokens t) { return json; } + private static MissingAclMode getMissingAclMode(ClientKey clientKey) { + return clientKey.hasRole(Role.ID_READER) ? MissingAclMode.ALLOW_ALL : MissingAclMode.DENY_ALL; + } + private JsonArray getAccessibleKeysAsJson(List keys, ClientKey clientKey) { - MissingAclMode mode = MissingAclMode.DENY_ALL; - if (clientKey.getRoles().contains(Role.ID_READER)) { - mode = MissingAclMode.ALLOW_ALL; - } + final MissingAclMode mode = getMissingAclMode(clientKey); KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); Map keysetMap = keyManagerSnapshot.getAllKeysets(); From b775b3c5284aa2985f2a4556b826fe6558fc161d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 1 Mar 2024 13:14:25 +1100 Subject: [PATCH 0163/1116] Added unit tests for OptOutCloudStorage --- pom.xml | 6 ++ .../operator/store/OptOutCloudStorage.java | 11 ++- .../store/OptOutCloudStorageTest.java | 78 +++++++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java diff --git a/pom.xml b/pom.xml index b47334061..4b4806094 100644 --- a/pom.xml +++ b/pom.xml @@ -187,6 +187,12 @@ 1.35 test + + org.instancio + instancio-junit + 4.3.2 + test + diff --git a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java index d9b50f64e..2cce2e93e 100644 --- a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java +++ b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java @@ -37,14 +37,19 @@ protected List extractListFromMetadata() throws CloudStorageException { String jsonString = Utils.readToEnd(input); if (jsonString != null && !jsonString.isEmpty()) { OptOutMetadata m = OptOutMetadata.fromJsonString(jsonString); - return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); + if (m != null) { + return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); + } else { + LOGGER.warn("Unable to parse the OptOut metadata into OptOutMetaData type. Start of the response from OptOut: {}", jsonString.substring(0, jsonString.length() > 50 ? 50 : jsonString.length())); + return new ArrayList(); + } } else { LOGGER.warn("Empty string returned from UidOptOutClient. Unable to read OptOut metadata"); return new ArrayList(); } - } catch (IOException e) { + } catch (Exception e) { // Intentionally not logging the exception as it may contain sensitive URLs - throw new CloudStorageException("extractListFromMetadata error"); + throw new CloudStorageException("extractListFromMetadata error."); } } } diff --git a/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java b/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java new file mode 100644 index 000000000..f0c285e49 --- /dev/null +++ b/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java @@ -0,0 +1,78 @@ +package com.uid2.operator.store; + +import com.uid2.shared.attest.UidOptOutClient; +import com.uid2.shared.cloud.CloudStorageException; +import com.uid2.shared.optout.OptOutMetadata; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.instancio.Instancio; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.ArgumentMatchers.anyString; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class OptOutCloudStorageTest { + private UidOptOutClient uidOptOutClient; + private OptOutCloudStorage optOutCloudStorage; + + @BeforeEach + public void setUp() { + this.uidOptOutClient = mock(UidOptOutClient.class); + this.optOutCloudStorage = new OptOutCloudStorage(this.uidOptOutClient, "/test/path"); + } + + @AfterEach + public void tearDown() throws Exception { + } + + @Test + public void extractListFromMetadata_success() throws CloudStorageException { + OptOutMetadata m = Instancio.create(OptOutMetadata.class); + + when(uidOptOutClient.download(anyString())).thenReturn(new ByteArrayInputStream(m.toJsonString().getBytes())); + + List response = this.optOutCloudStorage.extractListFromMetadata(); + + assertAll("extractListFromMetadata_success valid response", + () -> assertNotNull(response), + () -> assertEquals(m.optoutLogs.size(), response.size()), + () -> assertEquals(m.optoutLogs.stream().findFirst().get().location, response.get(0))); + } + + @Test + public void extractListFromMetadata_nullResponse() throws CloudStorageException { + when(uidOptOutClient.download(anyString())).thenReturn(null); + + assertThrows(CloudStorageException.class, + () -> this.optOutCloudStorage.extractListFromMetadata()); + } + + @Test + public void extractListFromMetadata_emptyResponse() throws CloudStorageException { + when(uidOptOutClient.download(anyString())).thenReturn(InputStream.nullInputStream()); + + List response = this.optOutCloudStorage.extractListFromMetadata(); + assertAll("extractListFromMetadata_success valid response", + () -> assertNotNull(response), + () -> assertEquals(0, response.size())); + } + + @Test + public void extractListFromMetadata_notJsonResponse() throws CloudStorageException { + when(uidOptOutClient.download(anyString())).thenReturn(new ByteArrayInputStream("Unauthorized".getBytes())); + + List response = this.optOutCloudStorage.extractListFromMetadata(); + assertAll("extractListFromMetadata_success valid response", + () -> assertNotNull(response), + () -> assertEquals(0, response.size())); + } +} From 0b90d831c793e8856ef1ae6b766fc2e97e9d993c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 1 Mar 2024 13:57:24 +1100 Subject: [PATCH 0164/1116] Throw exception on invalid response from OptOut --- .../java/com/uid2/operator/store/OptOutCloudStorage.java | 2 +- .../com/uid2/operator/store/OptOutCloudStorageTest.java | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java index 2cce2e93e..c7c6f087a 100644 --- a/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java +++ b/src/main/java/com/uid2/operator/store/OptOutCloudStorage.java @@ -41,7 +41,7 @@ protected List extractListFromMetadata() throws CloudStorageException { return m.optoutLogs.stream().map(o -> o.location).collect(Collectors.toList()); } else { LOGGER.warn("Unable to parse the OptOut metadata into OptOutMetaData type. Start of the response from OptOut: {}", jsonString.substring(0, jsonString.length() > 50 ? 50 : jsonString.length())); - return new ArrayList(); + throw new CloudStorageException("Invalid response returned from OptOut."); } } else { LOGGER.warn("Empty string returned from UidOptOutClient. Unable to read OptOut metadata"); diff --git a/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java b/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java index f0c285e49..e04b96fe7 100644 --- a/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java +++ b/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java @@ -70,9 +70,7 @@ public void extractListFromMetadata_emptyResponse() throws CloudStorageException public void extractListFromMetadata_notJsonResponse() throws CloudStorageException { when(uidOptOutClient.download(anyString())).thenReturn(new ByteArrayInputStream("Unauthorized".getBytes())); - List response = this.optOutCloudStorage.extractListFromMetadata(); - assertAll("extractListFromMetadata_success valid response", - () -> assertNotNull(response), - () -> assertEquals(0, response.size())); + assertThrows(CloudStorageException.class, + () -> this.optOutCloudStorage.extractListFromMetadata()); } } From eedc21dc75f0222df03bf3732dd5023a156f7e7e Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 1 Mar 2024 14:31:04 +1100 Subject: [PATCH 0165/1116] Removed unused code --- .../com/uid2/operator/store/OptOutCloudStorageTest.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java b/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java index e04b96fe7..2354e5c9b 100644 --- a/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java +++ b/src/test/java/com/uid2/operator/store/OptOutCloudStorageTest.java @@ -25,15 +25,11 @@ public class OptOutCloudStorageTest { private OptOutCloudStorage optOutCloudStorage; @BeforeEach - public void setUp() { + public void setup() { this.uidOptOutClient = mock(UidOptOutClient.class); this.optOutCloudStorage = new OptOutCloudStorage(this.uidOptOutClient, "/test/path"); } - @AfterEach - public void tearDown() throws Exception { - } - @Test public void extractListFromMetadata_success() throws CloudStorageException { OptOutMetadata m = Instancio.create(OptOutMetadata.class); @@ -61,7 +57,7 @@ public void extractListFromMetadata_emptyResponse() throws CloudStorageException when(uidOptOutClient.download(anyString())).thenReturn(InputStream.nullInputStream()); List response = this.optOutCloudStorage.extractListFromMetadata(); - assertAll("extractListFromMetadata_success valid response", + assertAll("extractListFromMetadata_emptyResponse empty list returned", () -> assertNotNull(response), () -> assertEquals(0, response.size())); } From 8ffba52529051403ee7de605953e1598fb919afe Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 1 Mar 2024 04:49:14 +0000 Subject: [PATCH 0166/1116] [CI Pipeline] Released Patch version: 5.27.36-96319170ee --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 061cba1fb..9d14a87ae 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.30-2ceb45287e + 5.27.36-96319170ee UTF-8 From 9b20201d24a601b9dff0d7dc5153959af0364990 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 15:10:55 +0800 Subject: [PATCH 0167/1116] Removed enforce HTTPS --- scripts/aws/entrypoint.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index c4095c395..1c735b1f5 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -19,13 +19,11 @@ if [ "${IDENTITY_SCOPE}" = "UID2" ]; then UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") - ENFORCE_HTTPS=$([[ "$(echo "${USER_DATA}" | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "false") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") - ENFORCE_HTTPS=$([[ "$(echo "${USER_DATA}" | grep ENFORCE_HTTPS=)" =~ ^export\ ENFORCE_HTTPS=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "false") else echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" exit 1 @@ -33,7 +31,6 @@ fi echo "UID2_CONFIG_SECRET_KEY=${UID2_CONFIG_SECRET_KEY}" echo "CORE_BASE_URL=${CORE_BASE_URL}" echo "OPTOUT_BASE_URL=${OPTOUT_BASE_URL}" -echo "ENFORCE_HTTPS=${ENFORCE_HTTPS}" export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r ".region") echo "AWS_REGION_NAME=${AWS_REGION_NAME}" @@ -99,12 +96,6 @@ if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_E sed -i "s#https://optout-prod.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" fi -# -- replace `enforce_https` value to ENFORCE_HTTPS if provided -if [ "${ENFORCE_HTTPS}" == false ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then - echo "Replacing enforce_https by ${ENFORCE_HTTPS}..." - jq_inplace_update_json "${FINAL_CONFIG}" enforce_https false -fi - cat "${FINAL_CONFIG}" # -- setup loki From fcb422b21f95984ec649d5bff0a4601545d18907 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 15:13:06 +0800 Subject: [PATCH 0168/1116] Commented pipeline for test --- .../publish-aws-nitro-enclave-docker.yaml | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 7efd54315..c13c31ff6 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -42,11 +42,11 @@ jobs: outputs: pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: - - name: Check branch and release type - id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 - with: - release_type: ${{ inputs.release_type }} +# - name: Check branch and release type +# id: checkRelease +# uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 +# with: +# release_type: ${{ inputs.release_type }} - name: Free up space run: | @@ -59,7 +59,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} - IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} +# IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - name: Checkout full history on Main uses: actions/checkout@v4 @@ -96,24 +96,24 @@ jobs: echo "Version number updated from $current_version to $new_version" echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT - - name: Commit pom.xml and version.json - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} - uses: EndBug/add-and-commit@v9 - with: - add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com - message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - - - name: Commit pom.xml, version.json and set tag - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} - uses: EndBug/add-and-commit@v9 - with: - add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com - message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} +# - name: Commit pom.xml and version.json +# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} +# uses: EndBug/add-and-commit@v9 +# with: +# add: 'pom.xml version.json' +# author_name: Release Workflow +# author_email: unifiedid-admin+release@thetradedesk.com +# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' +# +# - name: Commit pom.xml, version.json and set tag +# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} +# uses: EndBug/add-and-commit@v9 +# with: +# add: 'pom.xml version.json' +# author_name: Release Workflow +# author_email: unifiedid-admin+release@thetradedesk.com +# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' +# tag: v${{ steps.version.outputs.new_version }} - name: Run amazonlinux Docker image run: | From 35de0bc849322cb4dad51da803946f9a465ba5cd Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 15:28:03 +0800 Subject: [PATCH 0169/1116] Added AWS Docker cleanup --- .github/actions/build_aws_eif/action.yaml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 2deced658..eac2cea46 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -13,11 +13,15 @@ runs: using: "composite" steps: - - name: Run amazonlinux Docker image + - name: Cleanup shell: bash run: | docker stop $(docker ps -a -q) docker system prune -f + + - name: Run amazonlinux Docker image + shell: bash + run: | docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . docker run -d --privileged --name amazonlinux amazonlinux:latest @@ -66,3 +70,9 @@ runs: docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/uid2operator.eif docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ + + - name: Cleanup + shell: bash + run: | + docker stop $(docker ps -a -q) + docker system prune -f From 9a6cec1f640fabddde2319d951b767c027e15e54 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 16:04:52 +0800 Subject: [PATCH 0170/1116] Added space cleanup --- .github/actions/build_aws_eif/action.yaml | 6 ------ .github/workflows/publish-aws-nitro-enclave-docker.yaml | 9 ++++----- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index eac2cea46..0a075730d 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -13,12 +13,6 @@ runs: using: "composite" steps: - - name: Cleanup - shell: bash - run: | - docker stop $(docker ps -a -q) - docker system prune -f - - name: Run amazonlinux Docker image shell: bash run: | diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index c13c31ff6..8a8bcafbe 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,11 +115,6 @@ jobs: # message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' # tag: v${{ steps.version.outputs.new_version }} - - name: Run amazonlinux Docker image - run: | - docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . - docker run -d --privileged --name amazonlinux amazonlinux:latest - - name: Build UID2 AWS EIF uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: @@ -132,6 +127,10 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} + - name: Free up space + run: | + find . ! -name '${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}' -type f -exec rm -f {} + + - uses: actions/upload-artifact@v3 with: name: aws-nitro-deployment-files From 1c5be2cdd23d275eae078328dfa96df932e4a189 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 16:18:18 +0800 Subject: [PATCH 0171/1116] Updated action version number for testing --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 8a8bcafbe..d127b247b 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -116,13 +116,13 @@ jobs: # tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - name: Build EUID AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} From 27406052986cb812e59fcf9f63358798e748209e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 16:37:42 +0800 Subject: [PATCH 0172/1116] Updated space cleanup dir --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index d127b247b..3cdf1798f 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -48,7 +48,7 @@ jobs: # with: # release_type: ${{ inputs.release_type }} - - name: Free up space + - name: Free up space - delete preinstalled tools run: | rm -rf /opt/hostedtoolcache @@ -127,11 +127,12 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - - name: Free up space + - name: Test run: | - find . ! -name '${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}' -type f -exec rm -f {} + + ls . - uses: actions/upload-artifact@v3 with: name: aws-nitro-deployment-files path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} + if-no-files-found: error From 8e32573657e8169315d8a6969473912df4c02765 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Fri, 1 Mar 2024 17:22:40 +0800 Subject: [PATCH 0173/1116] Updated operator image description in pipeline --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ---- .github/workflows/run-e2e-tests-on-operator.yaml | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 3cdf1798f..680727ca7 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -127,10 +127,6 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - - name: Test - run: | - ls . - - uses: actions/upload-artifact@v3 with: name: aws-nitro-deployment-files diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 8aee690df..4415dc4d0 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -13,7 +13,7 @@ on: - azure - aws operator_image_version: - description: The pipeline will run the E2E test with this operator image version (for GCP, check http://us-docker.pkg.dev/uid2-prod-project/iabtechlab/uid2-operator) + description: The pipeline will run the E2E test with this operator image version (for GCP/Azure, check https://github.com/IABTechLab/uid2-operator/pkgs/container/uid2-operator) type: string default: latest core_image_version: From a3a0c5739ae14d54e5662593c4c1f475fc835d10 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 4 Mar 2024 02:14:16 +0000 Subject: [PATCH 0174/1116] [CI Pipeline] Released Patch version: 5.27.38-b871e92ffb --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d14a87ae..e95150c42 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.36-96319170ee + 5.27.38-b871e92ffb UTF-8 From bec7cd77de36fda4189f038bc4f6402ec9af95d6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 4 Mar 2024 08:32:29 +0000 Subject: [PATCH 0175/1116] [CI Pipeline] Released Patch version: 5.27.40-1e4b30dd6f --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e95150c42..ebf3e9d9d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.38-b871e92ffb + 5.27.40-1e4b30dd6f UTF-8 From a5306653cf44f8f701279fd77245a95269529bf0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 4 Mar 2024 22:35:01 +0000 Subject: [PATCH 0176/1116] [CI Pipeline] Released Patch version: 5.27.41-bec7cd77de --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ebf3e9d9d..44d5a2c69 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.40-1e4b30dd6f + 5.27.41-bec7cd77de UTF-8 From 65ce2c53433cd56071c5d09a92f69f2b922c8688 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 1 Mar 2024 11:40:57 +1100 Subject: [PATCH 0177/1116] Extract method getAccessibleKeys --- .../operator/vertx/UIDOperatorVerticle.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index ce46068aa..8284aa6b9 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1724,19 +1724,24 @@ private static MissingAclMode getMissingAclMode(ClientKey clientKey) { return clientKey.hasRole(Role.ID_READER) ? MissingAclMode.ALLOW_ALL : MissingAclMode.DENY_ALL; } - private JsonArray getAccessibleKeysAsJson(List keys, ClientKey clientKey) { + /** + * Returns the keyset keys that can be accessed by the site belonging to the specified client key. + */ + private static List getAccessibleKeys(List keys, KeyManagerSnapshot keyManagerSnapshot, ClientKey clientKey) { final MissingAclMode mode = getMissingAclMode(clientKey); + final KeysetSnapshot keysetSnapshot = keyManagerSnapshot.getKeysetSnapshot(); + + return keys.stream() + .filter(key -> keysetSnapshot.canClientAccessKey(clientKey, key, mode)) + .collect(Collectors.toList()); + } + private JsonArray getAccessibleKeysAsJson(List keys, ClientKey clientKey) { KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); Map keysetMap = keyManagerSnapshot.getAllKeysets(); - KeysetSnapshot keysetSnapshot = keyManagerSnapshot.getKeysetSnapshot(); final JsonArray a = new JsonArray(); - for (KeysetKey k : keys) { - if (!keysetSnapshot.canClientAccessKey(clientKey, k, mode)) { - continue; - } - + for (KeysetKey k : getAccessibleKeys(keys, keyManagerSnapshot, clientKey)) { final JsonObject o = new JsonObject(); o.put("id", k.getId()); o.put("created", k.getCreated().getEpochSecond()); From dd731aff03a2361e5b460e7c24fcb73ac7a41165 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 5 Mar 2024 13:20:36 +1100 Subject: [PATCH 0178/1116] Always return keys for master keyset --- src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 8284aa6b9..c32f98a49 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1726,13 +1726,14 @@ private static MissingAclMode getMissingAclMode(ClientKey clientKey) { /** * Returns the keyset keys that can be accessed by the site belonging to the specified client key. + * Keyset keys belonging to the master keyset can be accessed by any site. */ private static List getAccessibleKeys(List keys, KeyManagerSnapshot keyManagerSnapshot, ClientKey clientKey) { final MissingAclMode mode = getMissingAclMode(clientKey); final KeysetSnapshot keysetSnapshot = keyManagerSnapshot.getKeysetSnapshot(); return keys.stream() - .filter(key -> keysetSnapshot.canClientAccessKey(clientKey, key, mode)) + .filter(key -> key.getKeysetId() == Data.MasterKeysetId || keysetSnapshot.canClientAccessKey(clientKey, key, mode)) .collect(Collectors.toList()); } From b44d41c763f086b9e239f7d35b57162f7c4d981e Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 1 Mar 2024 13:19:41 +1100 Subject: [PATCH 0179/1116] Extract method toJson(KeysetKey) --- .../operator/vertx/UIDOperatorVerticle.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index c32f98a49..14c45b9c8 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -550,7 +550,7 @@ public void handleKeysSharing(RoutingContext rc) { // (b) a key belongs to master_keyset // otherwise, when a key is accessible by caller, the key can be used for decryption only. skip 'keyset_id' field. for (KeysetKey key: keysetKeyStore) { - JsonObject keyObj = new JsonObject(); + JsonObject keyObj = toJson(key); Keyset keyset = keysetMap.get(key.getKeysetId()); if (keyset == null || !keyset.isEnabled()) { @@ -562,11 +562,6 @@ public void handleKeysSharing(RoutingContext rc) { } else if (!keysetSnapshot.canClientAccessKey(clientKey, key, mode)) { continue; } - keyObj.put("id", key.getId()); - keyObj.put("created", key.getCreated().getEpochSecond()); - keyObj.put("activates", key.getActivates().getEpochSecond()); - keyObj.put("expires", key.getExpires().getEpochSecond()); - keyObj.put("secret", EncodingUtils.toBase64String(key.getKeyBytes())); keys.add(keyObj); accessibleSites.add(keyset.getSiteId()); } @@ -1743,18 +1738,27 @@ private JsonArray getAccessibleKeysAsJson(List keys, ClientKey client final JsonArray a = new JsonArray(); for (KeysetKey k : getAccessibleKeys(keys, keyManagerSnapshot, clientKey)) { - final JsonObject o = new JsonObject(); - o.put("id", k.getId()); - o.put("created", k.getCreated().getEpochSecond()); - o.put("activates", k.getActivates().getEpochSecond()); - o.put("expires", k.getExpires().getEpochSecond()); - o.put("secret", EncodingUtils.toBase64String(k.getKeyBytes())); + final JsonObject o = toJson(k); o.put("site_id", keysetMap.get(k.getKeysetId()).getSiteId()); a.add(o); } return a; } + /** + * Converts the specified keyset key to a JSON object. + * Includes the following fields: id, created, activates, expires, and secret. + */ + private static JsonObject toJson(KeysetKey key) { + final JsonObject json = new JsonObject(); + json.put("id", key.getId()); + json.put("created", key.getCreated().getEpochSecond()); + json.put("activates", key.getActivates().getEpochSecond()); + json.put("expires", key.getExpires().getEpochSecond()); + json.put("secret", EncodingUtils.toBase64String(key.getKeyBytes())); + return json; + } + private JsonObject toJson(IdentityTokens t) { final JsonObject json = new JsonObject(); json.put("advertisement_token", t.getAdvertisingToken()); From 27c8e4dc8c183e79812ea24b00d3039282d9c514 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 1 Mar 2024 13:43:58 +1100 Subject: [PATCH 0180/1116] Use getAccessibleKeys --- .../uid2/operator/vertx/UIDOperatorVerticle.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 14c45b9c8..9950993ec 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -517,13 +517,11 @@ public void handleKeysSharing(RoutingContext rc) { KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); List keysetKeyStore = keyManagerSnapshot.getKeysetKeys(); Map keysetMap = keyManagerSnapshot.getAllKeysets(); - KeysetSnapshot keysetSnapshot = keyManagerSnapshot.getKeysetSnapshot(); // defaultKeysetId allows calling sdk.Encrypt(rawUid) without specifying the keysetId Keyset defaultKeyset = keyManagerSnapshot.getDefaultKeyset(); // This will break if another Type is added to this map IRoleAuthorizable roleAuthorize = (IRoleAuthorizable) rc.data().get(API_CLIENT_PROP); - final MissingAclMode mode = getMissingAclMode(clientKey); final JsonObject resp = new JsonObject(); resp.put("caller_site_id", clientKey.getSiteId()); @@ -543,24 +541,21 @@ public void handleKeysSharing(RoutingContext rc) { } resp.put("identity_scope", this.identityScope.name()); - // include 'keyset_id' field, if: // (a) a key belongs to caller's enabled site // (b) a key belongs to master_keyset // otherwise, when a key is accessible by caller, the key can be used for decryption only. skip 'keyset_id' field. - for (KeysetKey key: keysetKeyStore) { + final List accessibleKeys = getAccessibleKeys(keysetKeyStore, keyManagerSnapshot, clientKey); + + for (KeysetKey key : accessibleKeys) { JsonObject keyObj = toJson(key); Keyset keyset = keysetMap.get(key.getKeysetId()); - if (keyset == null || !keyset.isEnabled()) { - continue; - } else if (clientKey.getSiteId() == keyset.getSiteId()) { + if (clientKey.getSiteId() == keyset.getSiteId()) { keyObj.put("keyset_id", key.getKeysetId()); } else if (key.getKeysetId() == Data.MasterKeysetId) { keyObj.put("keyset_id", MASTER_KEYSET_ID_FOR_SDKS); - } else if (!keysetSnapshot.canClientAccessKey(clientKey, key, mode)) { - continue; } keys.add(keyObj); accessibleSites.add(keyset.getSiteId()); From 9a2e5838c584bea3654e3e2fb52b02c895e9291e Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 5 Mar 2024 13:28:24 +1100 Subject: [PATCH 0181/1116] Move comment closer to code --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 9950993ec..f83dbfd29 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -542,16 +542,16 @@ public void handleKeysSharing(RoutingContext rc) { resp.put("identity_scope", this.identityScope.name()); - // include 'keyset_id' field, if: - // (a) a key belongs to caller's enabled site - // (b) a key belongs to master_keyset - // otherwise, when a key is accessible by caller, the key can be used for decryption only. skip 'keyset_id' field. final List accessibleKeys = getAccessibleKeys(keysetKeyStore, keyManagerSnapshot, clientKey); for (KeysetKey key : accessibleKeys) { JsonObject keyObj = toJson(key); Keyset keyset = keysetMap.get(key.getKeysetId()); + // include 'keyset_id' field, if: + // (a) a key belongs to caller's enabled site + // (b) a key belongs to master_keyset + // otherwise, when a key is accessible by caller, the key can be used for decryption only. skip 'keyset_id' field. if (clientKey.getSiteId() == keyset.getSiteId()) { keyObj.put("keyset_id", key.getKeysetId()); } else if (key.getKeysetId() == Data.MasterKeysetId) { From 0e804873933510e222a87c70684dc12323cbf4dd Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 5 Mar 2024 13:44:12 +1100 Subject: [PATCH 0182/1116] Move accessibleSites out of key loop --- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index f83dbfd29..9eb646263 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -512,7 +512,6 @@ public void handleKeysSharing(RoutingContext rc) { final ClientKey clientKey = AuthMiddleware.getAuthClient(ClientKey.class, rc); final JsonArray keys = new JsonArray(); final JsonArray sites = new JsonArray(); - final Set accessibleSites = new HashSet<>(); KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); List keysetKeyStore = keyManagerSnapshot.getKeysetKeys(); @@ -558,7 +557,6 @@ public void handleKeysSharing(RoutingContext rc) { keyObj.put("keyset_id", MASTER_KEYSET_ID_FOR_SDKS); } keys.add(keyObj); - accessibleSites.add(keyset.getSiteId()); } resp.put("keys", keys); //without cstg enabled, operator won't have site data and siteProvider could be null @@ -566,7 +564,13 @@ public void handleKeysSharing(RoutingContext rc) { //and we can still enable cstg feature but turn off site domain name download in // key/sharing endpoint if(keySharingEndpointProvideSiteDomainNames && clientSideTokenGenerate) { - for (Integer siteId : accessibleSites.stream().sorted().collect(Collectors.toList())) { + final List accessibleSites = accessibleKeys.stream() + .map(key -> keysetMap.get(key.getKeysetId()).getSiteId()) + .sorted() + .distinct() + .collect(Collectors.toUnmodifiableList()); + + for (Integer siteId : accessibleSites) { Site s = siteProvider.getSite(siteId); if(s == null || s.getDomainNames().isEmpty()) { continue; From 6e88bc6bde3d6f25abd394768f7f77ea07dd92f1 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 5 Mar 2024 14:42:57 +1100 Subject: [PATCH 0183/1116] Move variables closer to point of use --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 9eb646263..c911b4fdd 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -510,8 +510,6 @@ private String getSharingTokenExpirySeconds() { public void handleKeysSharing(RoutingContext rc) { try { final ClientKey clientKey = AuthMiddleware.getAuthClient(ClientKey.class, rc); - final JsonArray keys = new JsonArray(); - final JsonArray sites = new JsonArray(); KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); List keysetKeyStore = keyManagerSnapshot.getKeysetKeys(); @@ -543,6 +541,7 @@ public void handleKeysSharing(RoutingContext rc) { final List accessibleKeys = getAccessibleKeys(keysetKeyStore, keyManagerSnapshot, clientKey); + final JsonArray keys = new JsonArray(); for (KeysetKey key : accessibleKeys) { JsonObject keyObj = toJson(key); Keyset keyset = keysetMap.get(key.getKeysetId()); @@ -570,6 +569,7 @@ public void handleKeysSharing(RoutingContext rc) { .distinct() .collect(Collectors.toUnmodifiableList()); + final JsonArray sites = new JsonArray(); for (Integer siteId : accessibleSites) { Site s = siteProvider.getSite(siteId); if(s == null || s.getDomainNames().isEmpty()) { From 14520f7b3f58107a310a8c0c813ca901dc4d9d35 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 5 Mar 2024 22:04:31 +0800 Subject: [PATCH 0184/1116] Added HTTP to CF egress --- scripts/aws/UID_CloudFormation.template.yml | 31 ++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index 5c43450fb..bef78ce56 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -2,7 +2,7 @@ AWSTemplateFormatVersion: 2010-09-09 Description: UID 2.0 CloudFormation template Parameters: APIToken: - Description: UID API Token + Description: UID2 API Token Type: String NoEcho: true DeployToEnvironment: @@ -21,7 +21,7 @@ Parameters: AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. InstanceType: - Description: EC2 instance type, Minimum 4 Vcpu needed. + Description: EC2 instance type. Minimum 4 vCPUs needed. Type: String Default: m5.2xlarge AllowedValues: @@ -79,11 +79,11 @@ Metadata: - Subnet2Cidr ParameterLabels: APIToken: - default: OPERATOR_KEY provided by UID Administrator. + default: OPERATOR_KEY provided by UID2 Administrator. DeployToEnvironment: default: UID2 environment to deploy to. Prod - production; Integ - integration test. InstanceType: - default: Instance Type for EC2. Minimum 4 Vcpu needed. M5, M5a, M5n Instance types are tested. Choose 2xlarge or 4xlarge. + default: Instance Type for EC2. Minimum 4 vCPUs needed. M5, M5a, M5n Instance types are tested. Choose 2xlarge or 4xlarge. SSHKeyName: default: Key Name for SSH to EC2 (required) RootVolumeSize: @@ -91,11 +91,11 @@ Metadata: TrustNetworkCidr: default: Trusted Network CIDR (required) VpcId: - default: If choose to use Existing VPC, enter existing VPC Id (required in case of existing VPC) + default: If using an existing VPC, enter existing VPC ID (required in case of existing VPC) VpcSubnet: - default: If choose to use Existing VPC, enter existing Subnet Id (required in case of existing VPC) + default: If using an existing VPC, enter existing Subnet ID (required in case of existing VPC) CustomizeEnclaceResource: - default: Enclave resouce configuration auto calculated or manual + default: Enclave resource configuration auto calculated or manual EnclavememoryinMB: default: If choose to false for CustomizeEnclaceResource, enter memory for Enclave in MB EnclaveCPUCount: @@ -228,23 +228,28 @@ Resources: FromPort: '22' ToPort: '22' CidrIp: !Ref TrustNetworkCidr - Description: "Allow SSH" + Description: "Allow Inbound SSH" - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: !Ref TrustNetworkCidr - Description: "Allow HTTP" + Description: "Allow Inbound HTTP" - IpProtocol: tcp FromPort: '9080' ToPort: '9080' CidrIp: !Ref TrustNetworkCidr Description: "Prometheus metrics" SecurityGroupEgress: - - IpProtocol: 'tcp' - FromPort: 443 - ToPort: 443 + - IpProtocol: tcp + FromPort: '80' + ToPort: '80' + CidrIp: 0.0.0.0/0 + Description: "Allow Outbound HTTP" + - IpProtocol: tcp + FromPort: '443' + ToPort: '443' CidrIp: 0.0.0.0/0 - Description: "Allow Outbound" + Description: "Allow Outbound HTTPS" VpcId: !Ref VpcId LaunchTemplate: Type: AWS::EC2::LaunchTemplate From 7f133972b7991e073badaebad2db750c675a49bd Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Tue, 5 Mar 2024 09:08:30 -0800 Subject: [PATCH 0185/1116] Log origin field for InvalidHttpOrigin errors --- .../operator/vertx/UIDOperatorVerticle.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index b5c2a4760..f3ca2b131 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -5,6 +5,7 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.StatsCollectorHandler; +import com.uid2.operator.monitoring.StatsCollectorVerticle; import com.uid2.operator.monitoring.TokenResponseStatsCollector; import com.uid2.operator.privacy.tcf.TransparentConsent; import com.uid2.operator.privacy.tcf.TransparentConsentParseResult; @@ -50,6 +51,7 @@ import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.handler.CorsHandler; import io.vertx.ext.web.handler.StaticHandler; +import lombok.extern.flogger.Flogger; import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -103,10 +105,14 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final KeyManager keyManager; private final SecureLinkValidatorService secureLinkValidatorService; private final boolean cstgDoDomainNameCheck; + private final Duration invalidOriginProcessTimeInterval; + private final static long invalidOriginPerMin = 3600L; // We set the time interval to one hour public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); protected boolean keySharingEndpointProvideSiteDomainNames; + protected Map> invalidOriginMap; + private Instant lastInvalidOriginProcessTime; public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, @@ -144,6 +150,9 @@ public UIDOperatorVerticle(JsonObject config, this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; + this.invalidOriginProcessTimeInterval = Duration.ofMinutes(invalidOriginPerMin); + this.lastInvalidOriginProcessTime = Instant.now(); + this.invalidOriginMap = new HashMap<>(); } @Override @@ -309,6 +318,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA boolean allowedDomain = DomainNameCheckUtil.isDomainNameAllowed(origin, domainNames); if (!allowedDomain) { + handleInvalidHttpOriginError(clientSideKeypair.getSiteId(), origin); SendClientErrorResponseAndRecordStats(ResponseStatus.InvalidHttpOrigin, 403, rc, "unexpected http origin", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, siteProvider); return; } @@ -1758,6 +1768,18 @@ private void sendJsonResponse(RoutingContext rc, JsonArray json) { .end(json.encode()); } + private void handleInvalidHttpOriginError(int siteId, String origin) { + Set uniqueInvalidOrigins = invalidOriginMap.getOrDefault(siteId, new HashSet<>()); + uniqueInvalidOrigins.add(origin); + invalidOriginMap.put(siteId, uniqueInvalidOrigins); + + if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(invalidOriginProcessTimeInterval) >= 0) { + lastInvalidOriginProcessTime = Instant.now(); + LOGGER.error("Invalid origin: " + invalidOriginMap.toString()); + invalidOriginMap.clear(); + } + } + public enum UserConsentStatus { SUFFICIENT, INSUFFICIENT, From 99ba9c131c044baa6d9c2c874cb9c183bb77175d Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 6 Mar 2024 12:50:16 +1100 Subject: [PATCH 0186/1116] UID2-2888 address high vulnerability (#380) * Use kcc-UID2-2888-address-high-vulnerability * Update eclipse-temurin version * Update vertx to 4.5.3 * Add pull-requests: write for publishing gcp and azure * Test vulnerability scanner with HIGH severity for azure * Update Azure dockerfile to 124d6d14a08ad71b0c10b107f663de7b42787fb48cda8a82e5b1ca881772a832 * Revert changes to test HIGH vulnerability * Specify number to fix jvm error * Use d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a * Add vulnerability_severity as inputs * Revert change for jvm error * Add CVE-2023-52425 to trivyignore * Remove space between CRITICAL,HIGH * Update vulnerability_severity description * Add vulnerability_severity as inputs for gcp and all operator workflows * Update gcp docker file to d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a * Revert custom branch to v2 --- .github/workflows/publish-all-operators.yaml | 7 +++++++ .github/workflows/publish-azure-cc-enclave-docker.yaml | 8 +++++++- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 7 ++++++- .../workflows/publish-public-operator-docker-image.yaml | 5 +++++ .trivyignore | 1 + Dockerfile | 2 +- pom.xml | 2 +- scripts/azure-cc/Dockerfile | 2 +- scripts/gcp-oidc/Dockerfile | 2 +- 9 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 83769ae42..921674cc8 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -10,6 +10,10 @@ on: - Major - Minor - Patch + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' jobs: start: @@ -70,6 +74,7 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} + vulnerability_severity: ${{ inputs.vulnerability_severity }} secrets: inherit buildGCP: @@ -79,6 +84,7 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} + vulnerability_severity: ${{ inputs.vulnerability_severity }} secrets: inherit buildAzure: @@ -88,6 +94,7 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ needs.start.outputs.new_version }} + vulnerability_severity: ${{ inputs.vulnerability_severity }} secrets: inherit collectAllArtifacts: diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 81d545ed1..c24107ece 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -15,6 +15,11 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' + workflow_call: inputs: release_type: @@ -48,6 +53,7 @@ jobs: security-events: write packages: write id-token: write + pull-requests: write outputs: jar_version: ${{ steps.version.outputs.new_version }} image_tag: ${{ steps.updatePom.outputs.image_tag }} @@ -181,7 +187,7 @@ jobs: format: 'table' exit-code: '1' ignore-unfixed: true - severity: 'CRITICAL' + severity: ${{ inputs.vulnerability_severity }} hide-progress: true - name: Push to Docker diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 998e4d16e..b387de4c8 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -15,6 +15,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' workflow_call: inputs: release_type: @@ -50,6 +54,7 @@ jobs: security-events: write packages: write id-token: write + pull-requests: write outputs: jar_version: ${{ steps.version.outputs.new_version }} image_tag: ${{ steps.updatePom.outputs.image_tag }} @@ -217,7 +222,7 @@ jobs: format: 'table' exit-code: '1' ignore-unfixed: true - severity: 'CRITICAL' + severity: ${{ inputs.vulnerability_severity }} hide-progress: true - name: Push to Docker diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index c26d86135..aed55929d 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -15,6 +15,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' workflow_call: inputs: @@ -41,6 +45,7 @@ jobs: version_number_input: ${{ inputs.version_number_input }} cloud_provider: 'default' force_release: 'no' # Do not create a release for the component builds, will be created by the parent + vulnerability_severity: ${{ inputs.vulnerability_severity }} secrets: inherit e2e: diff --git a/.trivyignore b/.trivyignore index 3aa85f54a..4c55b7898 100644 --- a/.trivyignore +++ b/.trivyignore @@ -3,3 +3,4 @@ # for more details # e.g. # CVE-2022-3996 +CVE-2023-52425 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 5f66a0585..9e64d2deb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d +FROM eclipse-temurin@sha256:d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a WORKDIR /app EXPOSE 8080 diff --git a/pom.xml b/pom.xml index 44d5a2c69..bf9aeefe7 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ UTF-8 - 4.3.8 + 4.5.3 1.0.22 5.7.2 5.7.2 diff --git a/scripts/azure-cc/Dockerfile b/scripts/azure-cc/Dockerfile index d88f77077..a69e67619 100644 --- a/scripts/azure-cc/Dockerfile +++ b/scripts/azure-cc/Dockerfile @@ -1,4 +1,4 @@ -FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d +FROM eclipse-temurin@sha256:d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a # Install Packages RUN apk update && apk add jq diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 1da22360d..907ea7a96 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,4 +1,4 @@ -FROM eclipse-temurin@sha256:de8e6219ff5360811a453a9237713679a9d9106ba5150290ef37fb23e246ce7d +FROM eclipse-temurin@sha256:d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL" From 51b2f952f3f2987483c7f9c1e40df5a451ab449c Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 6 Mar 2024 12:56:16 +1100 Subject: [PATCH 0187/1116] Add vulnerability_severity to workflow_call inputs (#399) --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 4 ++++ .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 4 ++++ .github/workflows/publish-public-operator-docker-image.yaml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index c24107ece..96fee4414 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -30,6 +30,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' outputs: image_tag: diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index b387de4c8..b432f3043 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -29,6 +29,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' outputs: image_tag: diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index aed55929d..e398c7757 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -30,6 +30,10 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + vulnerability_severity: + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + type: string + default: 'CRITICAL,HIGH' outputs: image_tag: From 9f097086db39c0fe57260b87904dad3dcb187977 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 6 Mar 2024 01:57:23 +0000 Subject: [PATCH 0188/1116] [CI Pipeline] Released Patch version: 5.27.44-51b2f952f3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bf9aeefe7..f79d73763 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.41-bec7cd77de + 5.27.44-51b2f952f3 UTF-8 From 1c4e567dc038a9d52dba57eefb92792ef72cdcf0 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 6 Mar 2024 13:41:41 +1100 Subject: [PATCH 0189/1116] Rename workflow to shared-publish-java-to-docker-versioned (#401) * Rename workflow to shared-publish-java-to-docker-versioned * Update geekyeggo/delete-artifact to v4 --- .github/workflows/publish-all-operators.yaml | 2 +- .github/workflows/publish-public-operator-docker-image.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 921674cc8..c34216374 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -121,7 +121,7 @@ jobs: path: ./artifacts/azure_cc_operator - name: Delete staging artifacts - uses: geekyeggo/delete-artifact@v2 + uses: geekyeggo/delete-artifact@v4 with: name: | image-details diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index e398c7757..49a829b2b 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -43,7 +43,7 @@ on: jobs: image: name: Image - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-publish-docker-versioned.yaml@v2 + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-publish-java-to-docker-versioned.yaml@v2 with: release_type: ${{ inputs.release_type }} version_number_input: ${{ inputs.version_number_input }} From d5b110b0a05d38b6172da5b5656379dbea547395 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 6 Mar 2024 13:04:58 +0800 Subject: [PATCH 0190/1116] Removed CF HTTP egress --- scripts/aws/UID_CloudFormation.template.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index bef78ce56..88c885acc 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -240,11 +240,6 @@ Resources: CidrIp: !Ref TrustNetworkCidr Description: "Prometheus metrics" SecurityGroupEgress: - - IpProtocol: tcp - FromPort: '80' - ToPort: '80' - CidrIp: 0.0.0.0/0 - Description: "Allow Outbound HTTP" - IpProtocol: tcp FromPort: '443' ToPort: '443' From 379513c2e84f2a05f7572ccabbaffa8722e405f7 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 6 Mar 2024 16:12:23 +1100 Subject: [PATCH 0191/1116] Add jira ticket (#402) --- .trivyignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.trivyignore b/.trivyignore index 4c55b7898..3df38b54c 100644 --- a/.trivyignore +++ b/.trivyignore @@ -3,4 +3,6 @@ # for more details # e.g. # CVE-2022-3996 -CVE-2023-52425 \ No newline at end of file + +# https://atlassian.thetradedesk.com/jira/browse/UID2-2927 +CVE-2023-52425 From 6a583d60c664d4ba6fcc04118390ea8466335383 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 5 Mar 2024 14:50:37 +1100 Subject: [PATCH 0192/1116] Extract methods for sites --- .../operator/vertx/UIDOperatorVerticle.java | 77 +++++++++---------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index c911b4fdd..2e2a79d9a 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -558,49 +558,12 @@ public void handleKeysSharing(RoutingContext rc) { keys.add(keyObj); } resp.put("keys", keys); - //without cstg enabled, operator won't have site data and siteProvider could be null - //and adding keySharingEndpointProvideSiteDomainNames in case something goes wrong - //and we can still enable cstg feature but turn off site domain name download in - // key/sharing endpoint - if(keySharingEndpointProvideSiteDomainNames && clientSideTokenGenerate) { - final List accessibleSites = accessibleKeys.stream() - .map(key -> keysetMap.get(key.getKeysetId()).getSiteId()) - .sorted() - .distinct() - .collect(Collectors.toUnmodifiableList()); - - final JsonArray sites = new JsonArray(); - for (Integer siteId : accessibleSites) { - Site s = siteProvider.getSite(siteId); - if(s == null || s.getDomainNames().isEmpty()) { - continue; - } - JsonObject siteObj = new JsonObject(); - siteObj.put("id", siteId); - siteObj.put("domain_names", s.getDomainNames().stream().sorted().collect(Collectors.toList())); - sites.add(siteObj); - } - /* - The end result will look something like this: - "site_data": [ - { - "id": 101, - "domain_names": [ - "101.co.uk", - "101.com" - ] - }, - { - "id": 102, - "domain_names": [ - "102.co.uk", - "102.com" - ] - } - ] - */ - resp.put("site_data", sites); + + final List sites = getSitesWithDomainNames(accessibleKeys, keysetMap); + if (sites != null) { + resp.put("site_data", sites.stream().map(UIDOperatorVerticle::toJson).collect(Collectors.toList())); } + ResponseUtil.SuccessV2(rc, resp); } catch (Exception e) { LOGGER.error("handleKeysSharing", e); @@ -608,6 +571,36 @@ public void handleKeysSharing(RoutingContext rc) { } } + private List getSitesWithDomainNames(List keys, Map keysetMap) { + //without cstg enabled, operator won't have site data and siteProvider could be null + //and adding keySharingEndpointProvideSiteDomainNames in case something goes wrong + //and we can still enable cstg feature but turn off site domain name download in + // key/sharing endpoint + if (!keySharingEndpointProvideSiteDomainNames || !clientSideTokenGenerate) { + return null; + } + + return keys.stream() + .mapToInt(key -> keysetMap.get(key.getKeysetId()).getSiteId()) + .sorted() + .distinct() + .mapToObj(siteProvider::getSite) + .filter(Objects::nonNull) + .filter(site -> !site.getDomainNames().isEmpty()) + .collect(Collectors.toList()); + } + + /** + * Converts the specified site to a JSON object. + * Includes the following fields: id, domain_names. + */ + private static JsonObject toJson(Site site) { + JsonObject siteObj = new JsonObject(); + siteObj.put("id", site.getId()); + siteObj.put("domain_names", site.getDomainNames().stream().sorted().collect(Collectors.toList())); + return siteObj; + } + private void handleHealthCheck(RoutingContext rc) { if (HealthManager.instance.isHealthy()) { rc.response().end("OK"); From 3c763caf1c2e2a3008a2d3718d743d87d3dc984b Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 5 Mar 2024 15:37:09 +1100 Subject: [PATCH 0193/1116] Extract method addSharingHeaderFields --- .../operator/vertx/UIDOperatorVerticle.java | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 2e2a79d9a..52f349db1 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -68,7 +68,6 @@ import static com.uid2.operator.IdentityConst.*; import static com.uid2.operator.service.ResponseUtil.*; -import static com.uid2.shared.middleware.AuthMiddleware.API_CLIENT_PROP; public class UIDOperatorVerticle extends AbstractVerticle { private static final Logger LOGGER = LoggerFactory.getLogger(UIDOperatorVerticle.class); @@ -514,30 +513,9 @@ public void handleKeysSharing(RoutingContext rc) { KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); List keysetKeyStore = keyManagerSnapshot.getKeysetKeys(); Map keysetMap = keyManagerSnapshot.getAllKeysets(); - // defaultKeysetId allows calling sdk.Encrypt(rawUid) without specifying the keysetId - Keyset defaultKeyset = keyManagerSnapshot.getDefaultKeyset(); - - // This will break if another Type is added to this map - IRoleAuthorizable roleAuthorize = (IRoleAuthorizable) rc.data().get(API_CLIENT_PROP); final JsonObject resp = new JsonObject(); - resp.put("caller_site_id", clientKey.getSiteId()); - resp.put("master_keyset_id", MASTER_KEYSET_ID_FOR_SDKS); - if (defaultKeyset != null) { - resp.put("default_keyset_id", defaultKeyset.getKeysetId()); - } else if (roleAuthorize.hasRole(Role.SHARER)) { - LOGGER.warn(String.format("Cannot get a default keyset with SITE ID %d. Caller will not be able to encrypt tokens..", clientKey.getSiteId())); - } - // this is written out as a String, i.e. in the JSON response of key/sharing endpoint, it would show: - // "token_expiry_seconds" : "2592000" - // it should be an integer instead, but we can't change it until we confirm that the oldest version of each of our SDKs support this - resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); - - if (roleAuthorize.hasRole(Role.SHARER)) { - resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); - } - - resp.put("identity_scope", this.identityScope.name()); + addSharingHeaderFields(resp, keyManagerSnapshot, clientKey); final List accessibleKeys = getAccessibleKeys(keysetKeyStore, keyManagerSnapshot, clientKey); @@ -571,6 +549,30 @@ public void handleKeysSharing(RoutingContext rc) { } } + private void addSharingHeaderFields(JsonObject resp, KeyManagerSnapshot keyManagerSnapshot, ClientKey clientKey) { + resp.put("caller_site_id", clientKey.getSiteId()); + resp.put("master_keyset_id", MASTER_KEYSET_ID_FOR_SDKS); + + // defaultKeysetId allows calling sdk.Encrypt(rawUid) without specifying the keysetId + final Keyset defaultKeyset = keyManagerSnapshot.getDefaultKeyset(); + if (defaultKeyset != null) { + resp.put("default_keyset_id", defaultKeyset.getKeysetId()); + } else if (clientKey.hasRole(Role.SHARER)) { + LOGGER.warn(String.format("Cannot get a default keyset with SITE ID %d. Caller will not be able to encrypt tokens..", clientKey.getSiteId())); + } + + // this is written out as a String, i.e. in the JSON response of key/sharing endpoint, it would show: + // "token_expiry_seconds" : "2592000" + // it should be an integer instead, but we can't change it until we confirm that the oldest version of each of our SDKs support this + resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); + + if (clientKey.hasRole(Role.SHARER)) { + resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); + } + + resp.put("identity_scope", this.identityScope.name()); + } + private List getSitesWithDomainNames(List keys, Map keysetMap) { //without cstg enabled, operator won't have site data and siteProvider could be null //and adding keySharingEndpointProvideSiteDomainNames in case something goes wrong From 6b00871c30651e3e1a2e9a1843cbc41f41761301 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 6 Mar 2024 14:48:40 +1100 Subject: [PATCH 0194/1116] Add allow_clock_skew_seconds field --- src/main/java/com/uid2/operator/Const.java | 1 + src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/com/uid2/operator/Const.java b/src/main/java/com/uid2/operator/Const.java index fda0cf9e6..17609c5e4 100644 --- a/src/main/java/com/uid2/operator/Const.java +++ b/src/main/java/com/uid2/operator/Const.java @@ -13,6 +13,7 @@ public class Config extends com.uid2.shared.Const.Config { public static final String FailureShutdownWaitHoursProp = "failure_shutdown_wait_hours"; public static final String AllowLegacyAPIProp = "allow_legacy_api"; public static final String SharingTokenExpiryProp = "sharing_token_expiry_seconds"; + public static final String AllowClockSkewSecondsProp = "allow_clock_skew_seconds"; public static final String MaxSharingLifetimeProp = "max_sharing_lifetime_seconds"; public static final String EnableClientSideTokenGenerate = "client_side_token_generate"; public static final String ValidateServiceLinks = "validate_service_links"; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 52f349db1..5b2691be9 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -105,6 +105,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); + private final int allowClockSkewSeconds; protected int maxSharingLifetimeSeconds; protected boolean keySharingEndpointProvideSiteDomainNames; @@ -144,6 +145,7 @@ public UIDOperatorVerticle(JsonObject config, this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; + this.allowClockSkewSeconds = config.getInteger(Const.Config.AllowClockSkewSecondsProp, 1800); this.maxSharingLifetimeSeconds = config.getInteger(Const.Config.MaxSharingLifetimeProp, config.getInteger(Const.Config.SharingTokenExpiryProp)); } @@ -570,6 +572,7 @@ private void addSharingHeaderFields(JsonObject resp, KeyManagerSnapshot keyManag resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); } + resp.put("allow_clock_skew_seconds", allowClockSkewSeconds); resp.put("identity_scope", this.identityScope.name()); } From 682f30d0a5ae329f68bf4be376e100aab17a6a87 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 6 Mar 2024 15:47:00 +1100 Subject: [PATCH 0195/1116] Add /key/bidstream API endpoint --- src/main/java/com/uid2/operator/Const.java | 1 + .../operator/vertx/UIDOperatorVerticle.java | 61 +++++++++++++++++-- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/Const.java b/src/main/java/com/uid2/operator/Const.java index 17609c5e4..0d5bd59b9 100644 --- a/src/main/java/com/uid2/operator/Const.java +++ b/src/main/java/com/uid2/operator/Const.java @@ -13,6 +13,7 @@ public class Config extends com.uid2.shared.Const.Config { public static final String FailureShutdownWaitHoursProp = "failure_shutdown_wait_hours"; public static final String AllowLegacyAPIProp = "allow_legacy_api"; public static final String SharingTokenExpiryProp = "sharing_token_expiry_seconds"; + public static final String MaxBidstreamLifetimeSecondsProp = "max_bidstream_lifetime_seconds"; public static final String AllowClockSkewSecondsProp = "allow_clock_skew_seconds"; public static final String MaxSharingLifetimeProp = "max_sharing_lifetime_seconds"; public static final String EnableClientSideTokenGenerate = "client_side_token_generate"; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 5b2691be9..72cdf5d97 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -105,6 +105,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); + private final int maxBidstreamLifetimeSeconds; private final int allowClockSkewSeconds; protected int maxSharingLifetimeSeconds; protected boolean keySharingEndpointProvideSiteDomainNames; @@ -145,6 +146,12 @@ public UIDOperatorVerticle(JsonObject config, this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; + final Integer identityTokenExpiresAfterSeconds = config.getInteger(UIDOperatorService.IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS); + this.maxBidstreamLifetimeSeconds = config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp, identityTokenExpiresAfterSeconds); + if (this.maxBidstreamLifetimeSeconds < identityTokenExpiresAfterSeconds) { + LOGGER.error("Max bidstream lifetime seconds ({} seconds) is less than identity token lifetime ({} seconds)", maxBidstreamLifetimeSeconds, identityTokenExpiresAfterSeconds); + throw new RuntimeException("Max bidstream lifetime seconds is less than identity token lifetime seconds"); + } this.allowClockSkewSeconds = config.getInteger(Const.Config.AllowClockSkewSecondsProp, 1800); this.maxSharingLifetimeSeconds = config.getInteger(Const.Config.MaxSharingLifetimeProp, config.getInteger(Const.Config.SharingTokenExpiryProp)); } @@ -252,6 +259,8 @@ private void setupV2Routes(Router mainRouter, BodyHandler bodyHandler) { rc -> v2PayloadHandler.handle(rc, this::handleKeysRequestV2), Role.ID_READER)); v2Router.post("/key/sharing").handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleKeysSharing), Role.SHARER, Role.ID_READER)); + v2Router.post("/key/bidstream").handler(bodyHandler).handler(auth.handleV1( + rc -> v2PayloadHandler.handle(rc, this::handleKeysBidstream), Role.ID_READER)); v2Router.post("/token/logout").handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handleAsync(rc, this::handleLogoutAsyncV2), Role.OPTOUT)); @@ -539,10 +548,7 @@ public void handleKeysSharing(RoutingContext rc) { } resp.put("keys", keys); - final List sites = getSitesWithDomainNames(accessibleKeys, keysetMap); - if (sites != null) { - resp.put("site_data", sites.stream().map(UIDOperatorVerticle::toJson).collect(Collectors.toList())); - } + addSites(resp, accessibleKeys, keysetMap); ResponseUtil.SuccessV2(rc, resp); } catch (Exception e) { @@ -551,6 +557,43 @@ public void handleKeysSharing(RoutingContext rc) { } } + public void handleKeysBidstream(RoutingContext rc) { + final ClientKey clientKey = AuthMiddleware.getAuthClient(ClientKey.class, rc); + + final KeyManagerSnapshot keyManagerSnapshot = this.keyManager.getKeyManagerSnapshot(clientKey.getSiteId()); + final List keysetKeyStore = keyManagerSnapshot.getKeysetKeys(); + final Map keysetMap = keyManagerSnapshot.getAllKeysets(); + + final List accessibleKeys = getAccessibleKeys(keysetKeyStore, keyManagerSnapshot, clientKey); + + final List keysJson = accessibleKeys.stream() + .map(UIDOperatorVerticle::toJson) + .collect(Collectors.toList()); + + final JsonObject resp = new JsonObject(); + addBidstreamHeaderFields(resp); + resp.put("keys", keysJson); + addSites(resp, accessibleKeys, keysetMap); + + ResponseUtil.SuccessV2(rc, resp); + } + + private void addBidstreamHeaderFields(JsonObject resp) { + resp.put("max_bidstream_lifetime_seconds", maxBidstreamLifetimeSeconds); + addIdentityScopeField(resp); + addAllowClockSkewSecondsField(resp); + } + + private void addSites(JsonObject resp, List keys, Map keysetMap) { + final List sites = getSitesWithDomainNames(keys, keysetMap); + if (sites != null) { + final List sitesJson = sites.stream() + .map(UIDOperatorVerticle::toJson) + .collect(Collectors.toList()); + resp.put("site_data", sitesJson); + } + } + private void addSharingHeaderFields(JsonObject resp, KeyManagerSnapshot keyManagerSnapshot, ClientKey clientKey) { resp.put("caller_site_id", clientKey.getSiteId()); resp.put("master_keyset_id", MASTER_KEYSET_ID_FOR_SDKS); @@ -572,10 +615,18 @@ private void addSharingHeaderFields(JsonObject resp, KeyManagerSnapshot keyManag resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); } - resp.put("allow_clock_skew_seconds", allowClockSkewSeconds); + addIdentityScopeField(resp); + addAllowClockSkewSecondsField(resp); + } + + private void addIdentityScopeField(JsonObject resp) { resp.put("identity_scope", this.identityScope.name()); } + private void addAllowClockSkewSecondsField(JsonObject resp) { + resp.put("allow_clock_skew_seconds", allowClockSkewSeconds); + } + private List getSitesWithDomainNames(List keys, Map keysetMap) { //without cstg enabled, operator won't have site data and siteProvider could be null //and adding keySharingEndpointProvideSiteDomainNames in case something goes wrong From 4cc22b3b0eb0b81161e15d9175d9c17225542be3 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 6 Mar 2024 17:46:04 +1100 Subject: [PATCH 0196/1116] Set master keyset allowed sites to null in test data This matches production. --- .../com.uid2.core/test/keysets/keysets.json | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/resources/com.uid2.core/test/keysets/keysets.json b/src/main/resources/com.uid2.core/test/keysets/keysets.json index f5e5b29ab..e47eda1e2 100644 --- a/src/main/resources/com.uid2.core/test/keysets/keysets.json +++ b/src/main/resources/com.uid2.core/test/keysets/keysets.json @@ -1,16 +1,6 @@ [ { - "allowed_sites": [ - -1, - -2, - 2, - 3, - 4, - 5, - 6, - 7, - 8 - ], + "allowed_sites": null, "created": 1617149276, "default": true, "enabled": true, From 312d1dde3c13dbb53dcb02e800668a9c9679cabe Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Thu, 7 Mar 2024 09:51:29 +1100 Subject: [PATCH 0197/1116] Add test coverage for /key/bidstream --- .../operator/UIDOperatorVerticleTest.java | 119 +++++++++++++----- 1 file changed, 91 insertions(+), 28 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 7fffc0b90..cceb63065 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -395,7 +395,7 @@ private void checkEncryptionKeysResponse(JsonObject response, KeysetKey... expec } } - private void checkEncryptionKeysSharing(JsonObject response, int callersSiteId, KeysetKey... expectedKeys) { + private void checkEncryptionKeys(JsonObject response, SharingEndpoint endpoint, int callersSiteId, KeysetKey... expectedKeys) { assertEquals("success", response.getString("status")); final JsonArray responseKeys = response.getJsonObject("body").getJsonArray("keys"); assertNotNull(responseKeys); @@ -414,17 +414,41 @@ private void checkEncryptionKeysSharing(JsonObject response, int callersSiteId, assertTrue(expectedKeyset.isEnabled()); final var actualKeysetId = actualKey.getInteger("keyset_id"); - assertTrue(actualKeysetId == null || actualKeysetId > 0); //SDKs currently have an assumption that keyset ids are positive; that will be fixed. - if (expectedKeyset.getSiteId() == callersSiteId) { - assertEquals(expectedKey.getKeysetId(), actualKeysetId); - } else if (expectedKeyset.getSiteId() == MasterKeySiteId) { - assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, actualKeysetId); - } else { - assertNull(actualKeysetId); //we only send keyset ids if the caller is allowed to encrypt using that keyset (so only the caller's keysets and the master keyset) + + switch (endpoint) { + case SHARING: + assertTrue(actualKeysetId == null || actualKeysetId > 0); //SDKs currently have an assumption that keyset ids are positive; that will be fixed. + + if (expectedKeyset.getSiteId() == callersSiteId) { + assertEquals(expectedKey.getKeysetId(), actualKeysetId); + } else if (expectedKeyset.getSiteId() == MasterKeySiteId) { + assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, actualKeysetId); + } else { + assertNull(actualKeysetId); //we only send keyset ids if the caller is allowed to encrypt using that keyset (so only the caller's keysets and the master keyset) + } + break; + case BIDSTREAM: + assertNull(actualKeysetId); + break; } } } + private enum SharingEndpoint { + SHARING("/key/sharing"), + BIDSTREAM("/key/bidstream"); + + private String path; + + SharingEndpoint(String path) { + this.path = path; + } + + public String getPath() { + return this.path; + } + } + private void checkIdentityMapResponse(JsonObject response, String... expectedIdentifiers) { assertEquals("success", response.getString("status")); JsonObject body = response.getJsonObject("body"); @@ -3807,7 +3831,7 @@ void keySharingKeysets_CorrectFiltering(Vertx vertx, VertxTestContext testContex send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { System.out.println(respJson); - checkEncryptionKeysSharing(respJson, siteId, expectedKeys); + checkEncryptionKeys(respJson, SharingEndpoint.SHARING, siteId, expectedKeys); testContext.completeNow(); }); } @@ -3851,7 +3875,12 @@ public void verifyExpectedSiteDetail(HashMap> expectedSite } @ParameterizedTest - @ValueSource(booleans = {true, false}) + @CsvSource({ + "true, SHARING", + "false, SHARING", + "true, BIDSTREAM", + "false, BIDSTREAM", + }) // Tests: // ID_READER has access to a keyset that has the same site_id as ID_READER's - direct access // ID_READER has access to a keyset with a missing allowed_sites - access through sharing @@ -3859,7 +3888,7 @@ public void verifyExpectedSiteDetail(HashMap> expectedSite // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, Vertx vertx, VertxTestContext testContext) { + void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, SharingEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { if (!provideSiteDomainNames) { this.uidOperatorVerticle.setKeySharingEndpointProvideSiteDomainNames(false); @@ -3901,23 +3930,25 @@ void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, Vertx vertx, Ver doReturn(new Site(104, "site104", true, new HashSet<>())).when(siteProvider).getSite(104); Arrays.sort(expectedKeys, Comparator.comparing(KeysetKey::getId)); - send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { + send(apiVersion, vertx, apiVersion + endpoint.getPath(), true, null, null, 200, respJson -> { System.out.println(respJson); assertEquals("success", respJson.getString("status")); - assertEquals(clientSiteId, respJson.getJsonObject("body").getInteger("caller_site_id")); - assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, respJson.getJsonObject("body").getInteger("master_keyset_id")); - assertEquals(4, respJson.getJsonObject("body").getInteger("default_keyset_id")); - checkEncryptionKeysSharing(respJson, clientSiteId, expectedKeys); + + final JsonObject body = respJson.getJsonObject("body"); + + checkSharingResponseHeaderFields(endpoint, body, clientSiteId); + + checkEncryptionKeys(respJson, endpoint, clientSiteId, expectedKeys); if(provideSiteDomainNames) { HashMap> expectedSites = setupExpectation(101, 102); // site 104 has empty domain name list intentionally previously so while site 104 should be included in // this /key/sharing response, it won't appear in this domain name list - verifyExpectedSiteDetail(expectedSites, respJson.getJsonObject("body").getJsonArray("site_data")); + verifyExpectedSiteDetail(expectedSites, body.getJsonArray("site_data")); } else { //otherwise we shouldn't even have a 'sites' field - assertNull(respJson.getJsonObject("body").getJsonArray("site_data")); + assertNull(body.getJsonArray("site_data")); } testContext.completeNow(); }); @@ -3979,8 +4010,9 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int exp assertEquals(config.getInteger(Const.Config.SharingTokenExpiryProp), Integer.parseInt(respJson.getJsonObject("body").getString("token_expiry_seconds"))); assertEquals(expectedMaxSharingLifetimeSeconds, respJson.getJsonObject("body").getInteger("max_sharing_lifetime_seconds")); assertEquals(getIdentityScope().toString(), respJson.getJsonObject("body").getString("identity_scope")); + assertNotNull(respJson.getJsonObject("body").getInteger("allow_clock_skew_seconds")); - checkEncryptionKeysSharing(respJson, clientSiteId, expectedKeys); + checkEncryptionKeys(respJson, SharingEndpoint.SHARING, clientSiteId, expectedKeys); HashMap> expectedSites = setupExpectation(101, 104); verifyExpectedSiteDetail(expectedSites, respJson.getJsonObject("body").getJsonArray("site_data")); @@ -4008,7 +4040,7 @@ void keySharingKeysets_ReturnsMasterAndSite(Vertx vertx, VertxTestContext testCo send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { System.out.println(respJson); verifyExpectedSiteDetail(new HashMap<>(), respJson.getJsonObject("body").getJsonArray("site_data")); - checkEncryptionKeysSharing(respJson, siteId, encryptionKeys); + checkEncryptionKeys(respJson, SharingEndpoint.SHARING, siteId, encryptionKeys); testContext.completeNow(); }); } @@ -4082,13 +4114,25 @@ void keySharingKeysets_CorrectIDS(String testRun, Vertx vertx, VertxTestContext verifyExpectedSiteDetail(expectedSites, siteData); break; } - checkEncryptionKeysSharing(respJson, clientSiteId, expectedKeys); + checkEncryptionKeys(respJson, SharingEndpoint.SHARING, clientSiteId, expectedKeys); testContext.completeNow(); }); } + private static List keySharingRotatingKeysets_IDREADER_source() { + final String[] testRuns = {"KeysetAccess", "AddKeyset", "AddKey", "RotateKey", "DisableKey", "DisableKeyset"}; + + final List arguments = new ArrayList<>(); + for (SharingEndpoint endpoint : SharingEndpoint.values()) { + for (String testRun : testRuns) { + arguments.add(Arguments.of(testRun, endpoint)); + } + } + return arguments; + } + @ParameterizedTest - @ValueSource(strings = {"KeysetAccess", "AddKeyset", "AddKey", "RotateKey", "DisableKey", "DisableKeyset"}) + @MethodSource("keySharingRotatingKeysets_IDREADER_source") // "KeysetAccess" // ID_READER has access to a keyset that has the same site_id as ID_READER's - direct access // ID_READER has access to a keyset with a missing allowed_sites - access through sharing @@ -4096,7 +4140,7 @@ void keySharingKeysets_CorrectIDS(String testRun, Vertx vertx, VertxTestContext // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingRotatingKeysets_IDREADER(String testRun, Vertx vertx, VertxTestContext testContext) { + void keySharingRotatingKeysets_IDREADER(String testRun, SharingEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { String apiVersion = "v2"; int clientSiteId = 101; fakeAuth(clientSiteId, Role.ID_READER); @@ -4186,17 +4230,36 @@ void keySharingRotatingKeysets_IDREADER(String testRun, Vertx vertx, VertxTestCo // test and validate results expectedKeys.sort(Comparator.comparing(KeysetKey::getId)); - send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { + send(apiVersion, vertx, apiVersion + endpoint.getPath(), true, null, null, 200, respJson -> { System.out.println(respJson); assertEquals("success", respJson.getString("status")); - assertEquals(clientSiteId, respJson.getJsonObject("body").getInteger("caller_site_id")); - assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, respJson.getJsonObject("body").getInteger("master_keyset_id")); - assertEquals(4, respJson.getJsonObject("body").getInteger("default_keyset_id")); - checkEncryptionKeysSharing(respJson, clientSiteId, expectedKeys.toArray(new KeysetKey[0])); + final JsonObject body = respJson.getJsonObject("body"); + + checkSharingResponseHeaderFields(endpoint, body, clientSiteId); + + checkEncryptionKeys(respJson, endpoint, clientSiteId, expectedKeys.toArray(new KeysetKey[0])); testContext.completeNow(); }); } + private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObject body, int clientSiteId) { + assertEquals(this.getIdentityScope().toString(), body.getString("identity_scope")); + assertNotNull(body.getInteger("allow_clock_skew_seconds")); + + switch (endpoint) { + case SHARING: + assertEquals(clientSiteId, body.getInteger("caller_site_id")); + assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, body.getInteger("master_keyset_id")); + assertEquals(4, body.getInteger("default_keyset_id")); + // NOTE: this is intentionally a string, not an integer. See comment in UIDOperatorVerticle. + assertNotNull(body.getString("token_expiry_seconds")); + break; + case BIDSTREAM: + assertNotNull(body.getInteger("max_bidstream_lifetime_seconds")); + break; + } + } + @Test void secureLinkValidationPassesReturnsIdentity(Vertx vertx, VertxTestContext testContext) { JsonObject req = setupIdentityMapServiceLinkTest(); From 6e72ebc4c60c558190959e1795179c8f4aedf895 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 7 Mar 2024 12:00:44 +1100 Subject: [PATCH 0198/1116] Remove optout url from private operator --- conf/local-e2e-docker-private-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/local-e2e-docker-private-config.json b/conf/local-e2e-docker-private-config.json index 20b2ebb1a..947c2af3c 100644 --- a/conf/local-e2e-docker-private-config.json +++ b/conf/local-e2e-docker-private-config.json @@ -23,7 +23,7 @@ "validate_service_links": false, "optout_s3_bucket": "test-optout-bucket", "optout_s3_folder": "optout-v2/", - "optout_metadata_path": "http://optout:8081/optout/refresh", + "optout_metadata_path": "/optout/refresh", "optout_api_uri": "http://optout:8081/optout/replicate", "optout_delta_rotate_interval": 60, "cloud_refresh_interval": 30 From e017fb22de32b1714f6b3e8356d154834aa996a2 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 15:06:04 +0800 Subject: [PATCH 0199/1116] Removed commented code from testing --- .../publish-aws-nitro-enclave-docker.yaml | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 680727ca7..5663e93d7 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -42,11 +42,11 @@ jobs: outputs: pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: -# - name: Check branch and release type -# id: checkRelease -# uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 -# with: -# release_type: ${{ inputs.release_type }} + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + with: + release_type: ${{ inputs.release_type }} - name: Free up space - delete preinstalled tools run: | @@ -59,7 +59,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} -# IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} - name: Checkout full history on Main uses: actions/checkout@v4 @@ -96,24 +96,24 @@ jobs: echo "Version number updated from $current_version to $new_version" echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT -# - name: Commit pom.xml and version.json -# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} -# uses: EndBug/add-and-commit@v9 -# with: -# add: 'pom.xml version.json' -# author_name: Release Workflow -# author_email: unifiedid-admin+release@thetradedesk.com -# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' -# -# - name: Commit pom.xml, version.json and set tag -# if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} -# uses: EndBug/add-and-commit@v9 -# with: -# add: 'pom.xml version.json' -# author_name: Release Workflow -# author_email: unifiedid-admin+release@thetradedesk.com -# message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' -# tag: v${{ steps.version.outputs.new_version }} + - name: Commit pom.xml and version.json + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + + - name: Commit pom.xml, version.json and set tag + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} + uses: EndBug/add-and-commit@v9 + with: + add: 'pom.xml version.json' + author_name: Release Workflow + author_email: unifiedid-admin+release@thetradedesk.com + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline From ebcfbd1b3321ea5103acb4c8cbd28eda2fad2aae Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 15:11:10 +0800 Subject: [PATCH 0200/1116] Updated E2E test pipeline input param descriptions --- .../workflows/run-e2e-tests-on-operator.yaml | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 4415dc4d0..a5a96fce9 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -13,35 +13,35 @@ on: - azure - aws operator_image_version: - description: The pipeline will run the E2E test with this operator image version (for GCP/Azure, check https://github.com/IABTechLab/uid2-operator/pkgs/container/uid2-operator) + description: 'Image: Operator image version for public/gcp/azure (check https://github.com/IABTechLab/uid2-operator/pkgs/container/uid2-operator)' type: string default: latest core_image_version: - description: The pipeline will run the E2E test with this core image version + description: 'Image: Core image version' type: string default: latest optout_image_version: - description: The pipeline will run the E2E test with this optout image version + description: 'Image: Optout image version' type: string default: latest e2e_image_version: - description: The pipeline will run the E2E test with this E2E image version + description: 'Image: E2E image version' type: string default: latest core_branch: - description: 'Core: use this branch for Core config to test with' + description: 'Config: Core branch for config' type: string default: main optout_branch: - description: 'Optout: use this branch for Optout config to test with' + description: 'Config: Optout branch for config' type: string default: main admin_branch: - description: 'Admin: use this branch for Admin config to test with' + description: 'Config: Admin branch for config' type: string default: main operator_branch: - description: 'Operator: use this branch for Operator config to test with' + description: 'Config: Operator branch for config' type: string default: main aws: @@ -60,35 +60,35 @@ on: type: string default: public operator_image_version: - description: The pipeline will run the E2E test with this operator image version + description: 'Image: Operator image version for public/gcp/azure' type: string default: latest core_image_version: - description: The pipeline will run the E2E test with this core image version + description: 'Image: Core image version' type: string default: latest optout_image_version: - description: The pipeline will run the E2E test with this optout image version + description: 'Image: Optout image version' type: string default: latest e2e_image_version: - description: The pipeline will run the E2E test with this e2e image version + description: 'Image: E2E image version' type: string default: latest core_branch: - description: 'Core: use this branch for Core config to test with' + description: 'Config: Core branch for config' type: string default: main optout_branch: - description: 'Optout: use this branch for Optout config to test with' + description: 'Config: Optout branch for config' type: string default: main admin_branch: - description: 'Admin: use this branch for Admin config to test with' + description: 'Config: Admin branch for config' type: string default: main operator_branch: - description: 'Operator: use this branch for Operator config to test with' + description: 'Config: Operator branch for config' type: string default: main aws: From 12192d5cb35277b47e4708a1d78ad4178042026e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 17:03:44 +0800 Subject: [PATCH 0201/1116] Reverted repo versions to latest --- .../publish-aws-nitro-enclave-docker.yaml | 4 +- .../workflows/run-e2e-tests-on-operator.yaml | 61 +++++++++---------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 5663e93d7..16d112132 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -116,13 +116,13 @@ jobs: tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - name: Build EUID AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index a5a96fce9..f32b4dd9b 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -12,38 +12,37 @@ on: - gcp - azure - aws - operator_image_version: - description: 'Image: Operator image version for public/gcp/azure (check https://github.com/IABTechLab/uid2-operator/pkgs/container/uid2-operator)' - type: string - default: latest - core_image_version: - description: 'Image: Core image version' - type: string - default: latest - optout_image_version: - description: 'Image: Optout image version' - type: string - default: latest - e2e_image_version: - description: 'Image: E2E image version' - type: string - default: latest - core_branch: - description: 'Config: Core branch for config' - type: string - default: main - optout_branch: - description: 'Config: Optout branch for config' - type: string - default: main - admin_branch: - description: 'Config: Admin branch for config' + + identity_scope: + description: The identity scope [UID2, EUID] + required: true + type: choice + options: + - UID2 + - EUID + + image_version: + description: The image versions (for gcp/azure, set appropriate operator image) type: string - default: main - operator_branch: - description: 'Config: Operator branch for config' + required: true + default: '{ + "operator": "latest", + "core": "latest", + "optout": "latest", + "e2e": "latest" + }' + + branch: + description: The branches for config type: string - default: main + required: true + default: '{ + "operator": "main", + "core": "main", + "optout": "main", + "admin": "main", + }' + aws: description: The arguments for AWS private operator type: string @@ -103,7 +102,7 @@ on: jobs: e2e-test: name: E2E Test - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@gdm-UID2-2341-aws-test-pipeline + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@v2 with: operator_type: ${{ inputs.operator_type }} operator_image_version: ${{ inputs.operator_image_version }} From c8dee81d77bbac208a4b4e84bceb7055333995e6 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 17:18:17 +0800 Subject: [PATCH 0202/1116] Condensed E2E test pipeline input params --- .../publish-aws-nitro-enclave-docker.yaml | 4 +- .../workflows/run-e2e-tests-on-operator.yaml | 131 ++++++++---------- 2 files changed, 59 insertions(+), 76 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 5663e93d7..f60b09b66 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -116,13 +116,13 @@ jobs: tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2377-aws-euid with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - name: Build EUID AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2341-aws-test-pipeline + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@gdm-UID2-2377-aws-euid with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index a5a96fce9..2911c7dbc 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -8,42 +8,36 @@ on: required: true type: choice options: - - public - - gcp - - azure - - aws - operator_image_version: - description: 'Image: Operator image version for public/gcp/azure (check https://github.com/IABTechLab/uid2-operator/pkgs/container/uid2-operator)' - type: string - default: latest - core_image_version: - description: 'Image: Core image version' - type: string - default: latest - optout_image_version: - description: 'Image: Optout image version' - type: string - default: latest - e2e_image_version: - description: 'Image: E2E image version' - type: string - default: latest - core_branch: - description: 'Config: Core branch for config' - type: string - default: main - optout_branch: - description: 'Config: Optout branch for config' - type: string - default: main - admin_branch: - description: 'Config: Admin branch for config' + - public + - gcp + - azure + - aws + identity_scope: + description: The identity scope [UID2, EUID] + required: true + type: choice + options: + - UID2 + - EUID + image_version: + description: The image versions (for gcp/azure, set appropriate operator image) type: string - default: main - operator_branch: - description: 'Config: Operator branch for config' + required: true + default: '{ + "operator": "latest", + "core": "latest", + "optout": "latest" + }' + branch: + description: The branches for config type: string - default: main + required: true + default: '{ + "operator": "main", + "core": "main", + "optout": "main", + "admin": "main", + }' aws: description: The arguments for AWS private operator type: string @@ -51,7 +45,7 @@ on: "region": "us-east-1", "ami": "ami-xxxxx", "pcr0": "xxxxx" - }' + }' workflow_call: inputs: @@ -59,61 +53,50 @@ on: description: The operator type [public, gcp, azure, aws] type: string default: public - operator_image_version: - description: 'Image: Operator image version for public/gcp/azure' - type: string - default: latest - core_image_version: - description: 'Image: Core image version' - type: string - default: latest - optout_image_version: - description: 'Image: Optout image version' - type: string - default: latest - e2e_image_version: - description: 'Image: E2E image version' + identity_scope: + description: The identity scope [UID2, EUID] type: string - default: latest - core_branch: - description: 'Config: Core branch for config' + default: UID2 + image_version: + description: The image versions (for gcp/azure, set appropriate operator image) type: string - default: main - optout_branch: - description: 'Config: Optout branch for config' - type: string - default: main - admin_branch: - description: 'Config: Admin branch for config' - type: string - default: main - operator_branch: - description: 'Config: Operator branch for config' + default: '{ + "operator": "latest", + "core": "latest", + "optout": "latest" + }' + branch: + description: The branches for config type: string - default: main + default: '{ + "core": "main", + "optout": "main", + "admin": "main", + }' aws: description: The arguments for AWS private operator type: string default: '{ "region": "us-east-1", "ami": "ami-xxxxx", - "pcr0": "xxxxx" - }' + "pcr0": "xxxxx" + }' jobs: e2e-test: name: E2E Test - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@gdm-UID2-2341-aws-test-pipeline + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@gdm-UID2-2377-aws-euid with: operator_type: ${{ inputs.operator_type }} - operator_image_version: ${{ inputs.operator_image_version }} - core_image_version: ${{ inputs.core_image_version }} - optout_image_version: ${{ inputs.optout_image_version }} - e2e_image_version: ${{ inputs.e2e_image_version }} - core_branch: ${{ inputs.core_branch }} - optout_branch: ${{ inputs.optout_branch }} - admin_branch: ${{ inputs.admin_branch }} + operator_image_version: ${{ fromJson(inputs.image_version).operator }} + core_image_version: ${{ fromJson(inputs.image_version).core }} + optout_image_version: ${{ fromJson(inputs.image_version).optout }} + e2e_image_version: ${{ fromJson(inputs.image_version).e2e }} operator_branch: ${{ github.ref }} + core_branch: ${{ fromJson(inputs.branch).core }} + optout_branch: ${{ fromJson(inputs.branch).optout }} + admin_branch: ${{ fromJson(inputs.branch).admin }} + uid2_e2e_identity_scope: ${{ inputs.identity_scope }} gcp_workload_identity_provider_id: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER_ID }} gcp_service_account: ${{ vars.GCP_SERVICE_ACCOUNT }} gcp_project: ${{ vars.GCP_PROJECT }} From 527bf93162701eae8255540cb0982853a2f0d6fe Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 17:23:35 +0800 Subject: [PATCH 0203/1116] Updated CF templates formatting --- scripts/aws/EUID_CloudFormation.template.yml | 68 ++++++++++---------- scripts/aws/UID_CloudFormation.template.yml | 14 ++-- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/scripts/aws/EUID_CloudFormation.template.yml b/scripts/aws/EUID_CloudFormation.template.yml index 262de64e6..c435bb251 100644 --- a/scripts/aws/EUID_CloudFormation.template.yml +++ b/scripts/aws/EUID_CloudFormation.template.yml @@ -1,5 +1,5 @@ AWSTemplateFormatVersion: 2010-09-09 -Description: EUID CloudFormation template +Description: EUID 2.0 CloudFormation template Parameters: APIToken: Description: EUID API Token @@ -21,7 +21,7 @@ Parameters: AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. InstanceType: - Description: EC2 instance type, Minimum 4 Vcpu needed. + Description: EC2 instance type. Minimum 4 vCPUs needed. Type: String Default: m5.2xlarge AllowedValues: @@ -38,15 +38,15 @@ Parameters: Default: 15 VpcId: Type: String - Description: VpcId of your existing Virtual Private Cloud (VPC) + Description: VPC ID of your existing Virtual Private Cloud (VPC) Default: '' - ConstraintDescription: must be the VPC Id of an existing Virtual Private Cloud. + ConstraintDescription: must be the VPC ID of an existing Virtual Private Cloud. VpcSubnet1: - Description: AZ1 SubnetId from existing VPC, if using existing VPC + Description: AZ1 Subnet ID from existing VPC, if using existing VPC Type: String Default: '' VpcSubnet2: - Description: AZ2 SubnetId from existing VPC, if using existing VPC + Description: AZ2 Subnet ID from existing VPC, if using existing VPC Type: String Default: '' SSHKeyName: @@ -83,7 +83,7 @@ Metadata: DeployToEnvironment: default: EUID environment to deploy to. Prod - production; Integ - integration test. InstanceType: - default: Instance Type for EC2. Minimum 4 Vcpu needed. M5, M5a, M5n Instance types are tested. Choose 2xlarge or 4xlarge. + default: Instance Type for EC2. Minimum 4 vCPUs needed. M5, M5a, M5n Instance types are tested. Choose 2xlarge or 4xlarge. SSHKeyName: default: Key Name for SSH to EC2 (required) RootVolumeSize: @@ -91,11 +91,11 @@ Metadata: TrustNetworkCidr: default: Trusted Network CIDR (required) VpcId: - default: If choose to use Existing VPC, enter existing VPC Id (required in case of existing VPC) + default: If using an existing VPC, enter existing VPC ID (required in case of existing VPC) VpcSubnet: - default: If choose to use Existing VPC, enter existing Subnet Id (required in case of existing VPC) + default: If using an existing VPC, enter existing Subnet ID (required in case of existing VPC) CustomizeEnclaceResource: - default: Enclave resouce configuration auto calculated or manual + default: Enclave resource configuration auto calculated or manual EnclavememoryinMB: default: If choose to false for CustomizeEnclaceResource, enter memory for Enclave in MB EnclaveCPUCount: @@ -117,7 +117,7 @@ Mappings: Resources: KMSKey: Type: AWS::KMS::Key - Properties: + Properties: Description: Key for Secret Encryption EnableKeyRotation: true KeyPolicy: @@ -141,12 +141,12 @@ Resources: Resource: '*' SSMKEYAlias: Type: AWS::KMS::Alias - Properties: + Properties: AliasName: !Sub 'alias/euid-secret-${AWS::StackName}' TargetKeyId: !Ref KMSKey TokenSecret: Type: AWS::SecretsManager::Secret - Properties: + Properties: Description: EUID Token KmsKeyId: !GetAtt KMSKey.Arn Name: !Sub 'euid-config-stack-${AWS::StackName}' @@ -183,7 +183,7 @@ Resources: - Effect: Allow Action: 'secretsmanager:GetSecretValue' Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:euid-config-stack-${AWS::StackName}*' - ManagedPolicyArns: + ManagedPolicyArns: - 'arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy' WorkerInstanceProfile: Type: 'AWS::IAM::InstanceProfile' @@ -200,43 +200,43 @@ Resources: FromPort: '22' ToPort: '22' CidrIp: !Ref TrustNetworkCidr - Description: "Allow SSH" + Description: "Allow Inbound SSH" - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: !Ref TrustNetworkCidr - Description: "Allow HTTP" + Description: "Allow Inbound HTTP" - IpProtocol: tcp FromPort: '9080' ToPort: '9080' CidrIp: !Ref TrustNetworkCidr Description: "Prometheus metrics" SecurityGroupEgress: - - IpProtocol: 'tcp' - FromPort: 443 - ToPort: 443 + - IpProtocol: tcp + FromPort: '443' + ToPort: '443' CidrIp: 0.0.0.0/0 - Description: "Allow Outbound" + Description: "Allow Outbound HTTPS" VpcId: !Ref VpcId LaunchTemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateData: BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - Encrypted: true - VolumeSize: !Ref RootVolumeSize - VolumeType: gp3 + - DeviceName: /dev/xvda + Ebs: + Encrypted: true + VolumeSize: !Ref RootVolumeSize + VolumeType: gp3 IamInstanceProfile: Name: !Ref WorkerInstanceProfile ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI] InstanceType: !Ref InstanceType - EnclaveOptions: + EnclaveOptions: Enabled: true KeyName: !Ref SSHKeyName SecurityGroupIds: - - !Ref SecurityGroup + - !Ref SecurityGroup UserData: !Base64 Fn::Sub: | #!/bin/bash -ex @@ -254,18 +254,18 @@ Resources: LaunchTemplateId: !Ref LaunchTemplate Version: !GetAtt LaunchTemplate.LatestVersionNumber MetricsCollection: - - Granularity: 1Minute - Metrics: - - GroupTotalInstances + - Granularity: 1Minute + Metrics: + - GroupTotalInstances MaxSize: 1 MinSize: 1 - VPCZoneIdentifier: + VPCZoneIdentifier: - !Ref VpcSubnet1 - !Ref VpcSubnet2 Tags: - - Key: Name - Value: 'EUID Instance' - PropagateAtLaunch: true + - Key: Name + Value: 'EUID Instance' + PropagateAtLaunch: true CreationPolicy: ResourceSignal: Count: 1 diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index 88c885acc..3fca4d373 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -38,15 +38,15 @@ Parameters: Default: 15 VpcId: Type: String - Description: VpcId of your existing Virtual Private Cloud (VPC) + Description: VPC ID of your existing Virtual Private Cloud (VPC) Default: '' - ConstraintDescription: must be the VPC Id of an existing Virtual Private Cloud. + ConstraintDescription: must be the VPC ID of an existing Virtual Private Cloud. VpcSubnet1: - Description: AZ1 SubnetId from existing VPC, if using existing VPC + Description: AZ1 Subnet ID from existing VPC, if using existing VPC Type: String Default: '' VpcSubnet2: - Description: AZ2 SubnetId from existing VPC, if using existing VPC + Description: AZ2 Subnet ID from existing VPC, if using existing VPC Type: String Default: '' SSHKeyName: @@ -175,7 +175,7 @@ Resources: TokenSecret: Type: AWS::SecretsManager::Secret Properties: - Description: UID Token + Description: UID2 Token KmsKeyId: !GetAtt KMSKey.Arn Name: !Sub 'uid2-config-stack-${AWS::StackName}' SecretString: !Sub '{ @@ -222,7 +222,7 @@ Resources: SecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: - GroupDescription: UID EC2 Security Group + GroupDescription: UID2 EC2 Security Group SecurityGroupIngress: - IpProtocol: tcp FromPort: '22' @@ -292,7 +292,7 @@ Resources: - !Ref VpcSubnet2 Tags: - Key: Name - Value: 'UID Instance' + Value: 'UID2 Instance' PropagateAtLaunch: true CreationPolicy: ResourceSignal: From 9a5955428801facfe71a4b9b148801dca5ae9559 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 17:26:37 +0800 Subject: [PATCH 0204/1116] Updated input param formatting --- .github/workflows/run-e2e-tests-on-operator.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 2911c7dbc..16a1f41e7 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -26,17 +26,16 @@ on: default: '{ "operator": "latest", "core": "latest", - "optout": "latest" + "optout": "latest" }' branch: description: The branches for config type: string required: true default: '{ - "operator": "main", "core": "main", "optout": "main", - "admin": "main", + "admin": "main" }' aws: description: The arguments for AWS private operator @@ -63,7 +62,7 @@ on: default: '{ "operator": "latest", "core": "latest", - "optout": "latest" + "optout": "latest" }' branch: description: The branches for config @@ -71,7 +70,7 @@ on: default: '{ "core": "main", "optout": "main", - "admin": "main", + "admin": "main" }' aws: description: The arguments for AWS private operator From 70c327bb3101ba9dee07eace0505568ec04c1324 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Thu, 7 Mar 2024 17:39:08 +0800 Subject: [PATCH 0205/1116] Added E2E image version to input param --- .github/workflows/run-e2e-tests-on-operator.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 16a1f41e7..7de009f88 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -26,7 +26,8 @@ on: default: '{ "operator": "latest", "core": "latest", - "optout": "latest" + "optout": "latest", + "e2e": "latest" }' branch: description: The branches for config From 54a8b7601c1b205cb5a4fd70646ad013a5f41772 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Thu, 7 Mar 2024 17:13:22 -0800 Subject: [PATCH 0206/1116] Addressed comments and added unit tests --- conf/local-config.json | 3 +- conf/local-e2e-docker-public-config.json | 1 + conf/local-e2e-private-config.json | 3 +- conf/local-e2e-public-config.json | 3 +- ...dator-latest-e2e-docker-public-config.json | 1 + .../operator/vertx/UIDOperatorVerticle.java | 43 +++++++++++++------ .../operator/ExtendedUIDOperatorVerticle.java | 5 ++- .../operator/UIDOperatorVerticleTest.java | 38 ++++++++++++++++ 8 files changed, 79 insertions(+), 18 deletions(-) diff --git a/conf/local-config.json b/conf/local-config.json index 4e172ec2d..af46c8f61 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -34,5 +34,6 @@ "optout_partition_interval": 86400, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, - "key_sharing_endpoint_provide_site_domain_names": true + "key_sharing_endpoint_provide_site_domain_names": true, + "client_side_token_generate_log_invalid_http_origins": true } diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index b3157b064..70eaa049e 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -23,6 +23,7 @@ "enable_v2_encryption": true, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, + "client_side_token_generate_log_invalid_http_origins": true, "key_sharing_endpoint_provide_site_domain_names": true, "validate_service_links": true, "optout_s3_bucket": "test-optout-bucket", diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index 763231bd2..32b65e691 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -36,5 +36,6 @@ "optout_max_partitions": 30, "optout_partition_interval": 86400, "client_side_token_generate": true, - "client_side_token_generate_domain_name_check_enabled": false + "client_side_token_generate_domain_name_check_enabled": false, + "client_side_token_generate_log_invalid_http_origins": true } diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index 684ef73d6..a57f636aa 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -37,5 +37,6 @@ "optout_partition_interval": 86400, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, - "key_sharing_endpoint_provide_site_domain_names": true + "key_sharing_endpoint_provide_site_domain_names": true, + "client_side_token_generate_log_invalid_http_origins": true } diff --git a/conf/validator-latest-e2e-docker-public-config.json b/conf/validator-latest-e2e-docker-public-config.json index 87b042c7b..2b94970d2 100644 --- a/conf/validator-latest-e2e-docker-public-config.json +++ b/conf/validator-latest-e2e-docker-public-config.json @@ -24,6 +24,7 @@ "enable_v2_encryption": true, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, + "client_side_token_generate_log_invalid_http_origins": true, "key_sharing_endpoint_provide_site_domain_names": true, "validate_service_links": true, "optout_s3_bucket": "test-optout-bucket", diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index f3ca2b131..d9a307568 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -5,7 +5,6 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.StatsCollectorHandler; -import com.uid2.operator.monitoring.StatsCollectorVerticle; import com.uid2.operator.monitoring.TokenResponseStatsCollector; import com.uid2.operator.privacy.tcf.TransparentConsent; import com.uid2.operator.privacy.tcf.TransparentConsentParseResult; @@ -51,7 +50,6 @@ import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.handler.CorsHandler; import io.vertx.ext.web.handler.StaticHandler; -import lombok.extern.flogger.Flogger; import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,14 +103,13 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final KeyManager keyManager; private final SecureLinkValidatorService secureLinkValidatorService; private final boolean cstgDoDomainNameCheck; - private final Duration invalidOriginProcessTimeInterval; - private final static long invalidOriginPerMin = 3600L; // We set the time interval to one hour + private final boolean clientSideTokenGenerateLogInvalidHttpOrigin; public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); protected boolean keySharingEndpointProvideSiteDomainNames; - protected Map> invalidOriginMap; - private Instant lastInvalidOriginProcessTime; + private Map> siteIdToInvalidOrigins; + protected Instant lastInvalidOriginProcessTime; public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, @@ -150,9 +147,9 @@ public UIDOperatorVerticle(JsonObject config, this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; - this.invalidOriginProcessTimeInterval = Duration.ofMinutes(invalidOriginPerMin); this.lastInvalidOriginProcessTime = Instant.now(); - this.invalidOriginMap = new HashMap<>(); + this.siteIdToInvalidOrigins = new HashMap<>(); + this.clientSideTokenGenerateLogInvalidHttpOrigin = config.getBoolean("client_side_token_generate_log_invalid_http_origins", false); } @Override @@ -318,7 +315,9 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA boolean allowedDomain = DomainNameCheckUtil.isDomainNameAllowed(origin, domainNames); if (!allowedDomain) { - handleInvalidHttpOriginError(clientSideKeypair.getSiteId(), origin); + if (clientSideTokenGenerateLogInvalidHttpOrigin) { + handleInvalidHttpOriginError(clientSideKeypair.getSiteId(), origin); + } SendClientErrorResponseAndRecordStats(ResponseStatus.InvalidHttpOrigin, 403, rc, "unexpected http origin", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, siteProvider); return; } @@ -1769,17 +1768,33 @@ private void sendJsonResponse(RoutingContext rc, JsonArray json) { } private void handleInvalidHttpOriginError(int siteId, String origin) { - Set uniqueInvalidOrigins = invalidOriginMap.getOrDefault(siteId, new HashSet<>()); + Set uniqueInvalidOrigins = siteIdToInvalidOrigins.computeIfAbsent(siteId, k -> new HashSet<>()); uniqueInvalidOrigins.add(origin); - invalidOriginMap.put(siteId, uniqueInvalidOrigins); - if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(invalidOriginProcessTimeInterval) >= 0) { + if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(Duration.ofMinutes(1)) >= 0) { lastInvalidOriginProcessTime = Instant.now(); - LOGGER.error("Invalid origin: " + invalidOriginMap.toString()); - invalidOriginMap.clear(); + LOGGER.error(generateInvalidHttpOriginMessage(siteIdToInvalidOrigins)); + siteIdToInvalidOrigins.clear(); } } + private String generateInvalidHttpOriginMessage(Map> siteIdToInvalidOrigins) { + StringBuilder invalidHttpOriginMessage = new StringBuilder(); + invalidHttpOriginMessage.append("InvalidHttpOrigin: "); + siteIdToInvalidOrigins.forEach((siteId, origins) -> { + String siteName = getSiteName(siteProvider, siteId); + String site = "site " + siteName + " (" + siteId + "): "; + invalidHttpOriginMessage.append(site); + origins.forEach(origin -> invalidHttpOriginMessage.append(origin).append(", ")); + if (!origins.isEmpty()) { + invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 2, invalidHttpOriginMessage.length()); + } + invalidHttpOriginMessage.append(" | "); + }); + invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 3, invalidHttpOriginMessage.length()); + return invalidHttpOriginMessage.toString(); + } + public enum UserConsentStatus { SUFFICIENT, INSUFFICIENT, diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index 38f5eeb7c..d32e01849 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -4,13 +4,13 @@ import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.service.IUIDOperatorService; import com.uid2.operator.service.SecureLinkValidatorService; -import com.uid2.operator.service.UIDOperatorService; import com.uid2.operator.store.IOptOutStore; import com.uid2.operator.vertx.UIDOperatorVerticle; import com.uid2.shared.store.*; import io.vertx.core.json.JsonObject; import java.time.Clock; +import java.time.Instant; //An extended UIDOperatorVerticle to expose classes for testing purposes public class ExtendedUIDOperatorVerticle extends UIDOperatorVerticle { @@ -36,4 +36,7 @@ public void setKeySharingEndpointProvideSiteDomainNames(boolean enable) { this.keySharingEndpointProvideSiteDomainNames = enable; } + public void setlastInvalidOriginProcessTime(Instant lastInvalidOriginProcessTime) { + this.lastInvalidOriginProcessTime = lastInvalidOriginProcessTime; + } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b73531183..c2ac63e5c 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1,5 +1,8 @@ package com.uid2.operator; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; import com.uid2.operator.model.*; import com.uid2.operator.model.IdentityScope; import com.uid2.operator.monitoring.IStatsCollectorQueue; @@ -48,6 +51,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.slf4j.LoggerFactory; import javax.crypto.SecretKey; import java.math.BigInteger; @@ -148,6 +152,7 @@ private void setupConfig(JsonObject config) { config.put("identity_v3", useIdentityV3()); config.put("client_side_token_generate", true); config.put("key_sharing_endpoint_provide_site_domain_names", true); + config.put("client_side_token_generate_log_invalid_http_origins", true); } private static byte[] makeAesKey(String prefix) { @@ -2723,6 +2728,39 @@ void cstgDomainNameCheckFails(boolean setOptoutCheckFlagInRequest, String httpOr }); } + @ParameterizedTest + @CsvSource({ + "true,http://gototest.com", + "false,http://gototest.com", + }) + void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagInRequest, String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); + this.uidOperatorVerticle.setlastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); + + setupCstgBackend(); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); + sendCstg(vertx, + "v2/token/client-generate", + httpOrigin, + data.getItem1(), + data.getItem2(), + 403, + testContext, + respJson -> { + assertFalse(respJson.containsKey("body")); + assertEquals("unexpected http origin", respJson.getString("message")); + assertEquals("invalid_http_origin", respJson.getString("status")); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOrigin: site test (123): http://gototest.com")); + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin); + testContext.completeNow(); + }); + } + @ParameterizedTest @CsvSource({ "true,https://cstg.co.uk", From e9e76bc7c6de5c50bab643c59c0182f7a47e096c Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Thu, 7 Mar 2024 18:17:48 -0800 Subject: [PATCH 0207/1116] Address the comment --- .../uid2/operator/vertx/UIDOperatorVerticle.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index d9a307568..db3856f3e 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1771,7 +1771,7 @@ private void handleInvalidHttpOriginError(int siteId, String origin) { Set uniqueInvalidOrigins = siteIdToInvalidOrigins.computeIfAbsent(siteId, k -> new HashSet<>()); uniqueInvalidOrigins.add(origin); - if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(Duration.ofMinutes(1)) >= 0) { + if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(Duration.ofMinutes(60)) >= 0) { lastInvalidOriginProcessTime = Instant.now(); LOGGER.error(generateInvalidHttpOriginMessage(siteIdToInvalidOrigins)); siteIdToInvalidOrigins.clear(); @@ -1781,17 +1781,23 @@ private void handleInvalidHttpOriginError(int siteId, String origin) { private String generateInvalidHttpOriginMessage(Map> siteIdToInvalidOrigins) { StringBuilder invalidHttpOriginMessage = new StringBuilder(); invalidHttpOriginMessage.append("InvalidHttpOrigin: "); - siteIdToInvalidOrigins.forEach((siteId, origins) -> { + for (Map.Entry> entry : siteIdToInvalidOrigins.entrySet()) { + int siteId = entry.getKey(); + Set origins = entry.getValue(); String siteName = getSiteName(siteProvider, siteId); String site = "site " + siteName + " (" + siteId + "): "; invalidHttpOriginMessage.append(site); - origins.forEach(origin -> invalidHttpOriginMessage.append(origin).append(", ")); + for (String origin : origins) { + invalidHttpOriginMessage.append(origin).append(", "); + } if (!origins.isEmpty()) { invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 2, invalidHttpOriginMessage.length()); } invalidHttpOriginMessage.append(" | "); - }); - invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 3, invalidHttpOriginMessage.length()); + } + if (!siteIdToInvalidOrigins.isEmpty()) { + invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 3, invalidHttpOriginMessage.length()); + } return invalidHttpOriginMessage.toString(); } From 61760a4be24de687a96c63661d27a391b610cd85 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 15:04:26 +1100 Subject: [PATCH 0208/1116] Clarify comment about when to include keyset ID --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 72cdf5d97..b0318e91a 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -535,10 +535,10 @@ public void handleKeysSharing(RoutingContext rc) { JsonObject keyObj = toJson(key); Keyset keyset = keysetMap.get(key.getKeysetId()); - // include 'keyset_id' field, if: - // (a) a key belongs to caller's enabled site - // (b) a key belongs to master_keyset - // otherwise, when a key is accessible by caller, the key can be used for decryption only. skip 'keyset_id' field. + // Include keyset ID if: + // - The key belongs to the caller's site, or + // - The key belongs to the master keyset. + // Otherwise, the key can be used for decryption only so we don't include the keyset ID. if (clientKey.getSiteId() == keyset.getSiteId()) { keyObj.put("keyset_id", key.getKeysetId()); } else if (key.getKeysetId() == Data.MasterKeysetId) { From 27466e38bf7583d41a0e5cdcb49f16cca5c31728 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 15:35:51 +1100 Subject: [PATCH 0209/1116] Check that /key/sharing header fields are not present in /key/bidstream response --- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index cceb63065..d1fff4c75 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4256,6 +4256,13 @@ private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObje break; case BIDSTREAM: assertNotNull(body.getInteger("max_bidstream_lifetime_seconds")); + + // Check that /key/sharing header fields are not present. + assertFalse(body.containsKey("caller_site_id")); + assertFalse(body.containsKey("default_keyset_id")); + assertFalse(body.containsKey("master_keyset_id")); + assertFalse(body.containsKey("max_sharing_lifetime_seconds")); + assertFalse(body.containsKey("token_expiry_seconds")); break; } } From 180237cc291bfa8b7c856ebfb8dbdb6312e58f7a Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Thu, 7 Mar 2024 21:21:29 -0800 Subject: [PATCH 0210/1116] Address the comments --- .../operator/vertx/UIDOperatorVerticle.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index db3856f3e..b995b8d9d 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1781,22 +1781,25 @@ private void handleInvalidHttpOriginError(int siteId, String origin) { private String generateInvalidHttpOriginMessage(Map> siteIdToInvalidOrigins) { StringBuilder invalidHttpOriginMessage = new StringBuilder(); invalidHttpOriginMessage.append("InvalidHttpOrigin: "); + boolean mapHasFirstEle = false; for (Map.Entry> entry : siteIdToInvalidOrigins.entrySet()) { + if(mapHasFirstEle) { + invalidHttpOriginMessage.append(" | "); + } + mapHasFirstEle = true; int siteId = entry.getKey(); Set origins = entry.getValue(); String siteName = getSiteName(siteProvider, siteId); String site = "site " + siteName + " (" + siteId + "): "; invalidHttpOriginMessage.append(site); + boolean setHasFirstEle = false; for (String origin : origins) { - invalidHttpOriginMessage.append(origin).append(", "); - } - if (!origins.isEmpty()) { - invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 2, invalidHttpOriginMessage.length()); + if(setHasFirstEle) { + invalidHttpOriginMessage.append(", "); + } + setHasFirstEle = true; + invalidHttpOriginMessage.append(origin); } - invalidHttpOriginMessage.append(" | "); - } - if (!siteIdToInvalidOrigins.isEmpty()) { - invalidHttpOriginMessage.delete(invalidHttpOriginMessage.length() - 3, invalidHttpOriginMessage.length()); } return invalidHttpOriginMessage.toString(); } From e08166ab6e5461cd57c30c062e9f640eb8910024 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 15:57:22 +1100 Subject: [PATCH 0211/1116] Check that /key/bidstream header fields are not present in /key/sharing response --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index d1fff4c75..4ecdc2c9b 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4253,6 +4253,9 @@ private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObje assertEquals(4, body.getInteger("default_keyset_id")); // NOTE: this is intentionally a string, not an integer. See comment in UIDOperatorVerticle. assertNotNull(body.getString("token_expiry_seconds")); + + // Check that /key/bidstream fields are not present. + assertFalse(body.containsKey("max_bidstream_lifetime_seconds")); break; case BIDSTREAM: assertNotNull(body.getInteger("max_bidstream_lifetime_seconds")); From cca3c94e7fcdd4fafdb599fa16e7185cc48e6068 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 16:07:10 +1100 Subject: [PATCH 0212/1116] Assert on allow_clock_skew_seconds values --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 4ecdc2c9b..7d60cf20b 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -149,6 +149,8 @@ private void setupConfig(JsonObject config) { config.put("identity_v3", useIdentityV3()); config.put("client_side_token_generate", true); config.put("key_sharing_endpoint_provide_site_domain_names", true); + + config.put(Const.Config.AllowClockSkewSecondsProp, 3600); } private static byte[] makeAesKey(String prefix) { @@ -4244,7 +4246,7 @@ void keySharingRotatingKeysets_IDREADER(String testRun, SharingEndpoint endpoint private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObject body, int clientSiteId) { assertEquals(this.getIdentityScope().toString(), body.getString("identity_scope")); - assertNotNull(body.getInteger("allow_clock_skew_seconds")); + assertEquals(config.getInteger(Const.Config.AllowClockSkewSecondsProp), body.getInteger("allow_clock_skew_seconds")); switch (endpoint) { case SHARING: From 03ec647e935cbbf878825a327ef86eddded27b89 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 16:26:23 +1100 Subject: [PATCH 0213/1116] Assert on max_bidstream_lifetime_seconds value --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 7d60cf20b..a53893f16 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -151,6 +151,7 @@ private void setupConfig(JsonObject config) { config.put("key_sharing_endpoint_provide_site_domain_names", true); config.put(Const.Config.AllowClockSkewSecondsProp, 3600); + config.put(Const.Config.MaxBidstreamLifetimeSecondsProp, identityExpiresAfter.toSeconds() + 10); } private static byte[] makeAesKey(String prefix) { @@ -4260,7 +4261,7 @@ private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObje assertFalse(body.containsKey("max_bidstream_lifetime_seconds")); break; case BIDSTREAM: - assertNotNull(body.getInteger("max_bidstream_lifetime_seconds")); + assertEquals(config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp), body.getInteger("max_bidstream_lifetime_seconds")); // Check that /key/sharing header fields are not present. assertFalse(body.containsKey("caller_site_id")); From d092f377d5ecc89ee3cba12b2fea4e3b3a9d9d69 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 16:26:46 +1100 Subject: [PATCH 0214/1116] Assert on token_expiry_seconds value --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index a53893f16..db1af6fc1 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4255,7 +4255,7 @@ private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObje assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, body.getInteger("master_keyset_id")); assertEquals(4, body.getInteger("default_keyset_id")); // NOTE: this is intentionally a string, not an integer. See comment in UIDOperatorVerticle. - assertNotNull(body.getString("token_expiry_seconds")); + assertEquals(config.getInteger(Const.Config.SharingTokenExpiryProp), Integer.parseInt(body.getString("token_expiry_seconds"))); // Check that /key/bidstream fields are not present. assertFalse(body.containsKey("max_bidstream_lifetime_seconds")); From 65470170b493b272eb8ae47931d3c8ee50f0a5c6 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 17:44:20 +1100 Subject: [PATCH 0215/1116] Add max_sharing_lifetime_seconds to config files Add ten second buffer because some tokens have a lifetime that is slightly longer than it ought to be. --- conf/default-config.json | 3 ++- conf/local-config.json | 1 + conf/local-e2e-private-config.json | 1 + conf/local-e2e-public-config.json | 1 + scripts/aws/conf/default-config.json | 1 + scripts/azure-cc/conf/default-config.json | 1 + scripts/gcp-oidc/conf/default-config.json | 1 + scripts/gcp/conf/integ-config.json | 3 ++- scripts/gcp/conf/prod-config.json | 3 ++- 9 files changed, 12 insertions(+), 3 deletions(-) diff --git a/conf/default-config.json b/conf/default-config.json index 6469529e9..77cdf571d 100644 --- a/conf/default-config.json +++ b/conf/default-config.json @@ -32,5 +32,6 @@ "optout_inmem_cache": false, "enclave_platform": null, "failure_shutdown_wait_hours": 120, - "sharing_token_expiry_seconds": 2592000 + "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010 } diff --git a/conf/local-config.json b/conf/local-config.json index 4e172ec2d..e8d7922a8 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -19,6 +19,7 @@ "identity_scope": "uid2", "enable_v2_encryption": false, "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index 763231bd2..e09749d47 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -22,6 +22,7 @@ "identity_scope": "uid2", "enable_v2_encryption": true, "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index 684ef73d6..8c24e17bf 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -22,6 +22,7 @@ "identity_scope": "uid2", "enable_v2_encryption": true, "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/scripts/aws/conf/default-config.json b/scripts/aws/conf/default-config.json index 4146e55c0..352fcd45b 100644 --- a/scripts/aws/conf/default-config.json +++ b/scripts/aws/conf/default-config.json @@ -33,6 +33,7 @@ "enclave_platform": null, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010, "validate_service_links": false, "advertising_token_v4_percentage": 0 } diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index c0684b85f..ca85949b2 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -37,6 +37,7 @@ "allow_legacy_api": false, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010, "validate_service_links": false, "advertising_token_v4_percentage": 0 } diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index c744175a2..209d677bf 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -37,6 +37,7 @@ "allow_legacy_api": false, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010, "validate_service_links": false, "advertising_token_v4_percentage": 0 } diff --git a/scripts/gcp/conf/integ-config.json b/scripts/gcp/conf/integ-config.json index 7223450e5..5bc91520c 100644 --- a/scripts/gcp/conf/integ-config.json +++ b/scripts/gcp/conf/integ-config.json @@ -14,5 +14,6 @@ "enclave_platform": "gcp-vmid", "service_instances": 16, "allow_legacy_api": false, - "sharing_token_expiry_seconds": 2592000 + "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010 } diff --git a/scripts/gcp/conf/prod-config.json b/scripts/gcp/conf/prod-config.json index 17f85276b..09d7e760a 100644 --- a/scripts/gcp/conf/prod-config.json +++ b/scripts/gcp/conf/prod-config.json @@ -14,5 +14,6 @@ "enclave_platform": "gcp-vmid", "service_instances": 16, "allow_legacy_api": false, - "sharing_token_expiry_seconds": 2592000 + "sharing_token_expiry_seconds": 2592000, + "max_sharing_lifetime_seconds": 2592010 } From 8d0c35d2e2d843c6f96174fe60cb77e1378db812 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 8 Mar 2024 17:45:11 +1100 Subject: [PATCH 0216/1116] Add max_bidstream_lifetime_seconds to config files Add ten second buffer because some tokens have a lifetime that is slightly longer than it ought to be. --- conf/docker-config.json | 1 + conf/local-config.json | 1 + conf/local-e2e-docker-private-config.json | 1 + conf/local-e2e-docker-public-config.json | 1 + conf/local-e2e-private-config.json | 1 + conf/local-e2e-public-config.json | 1 + conf/validator-latest-e2e-docker-public-config.json | 1 + scripts/aws/conf/prod-euid-config.json | 1 + scripts/aws/conf/prod-uid2-config.json | 1 + scripts/azure-cc/conf/default-config.json | 1 + scripts/azure-cc/conf/prod-uid2-config.json | 3 ++- scripts/gcp-oidc/conf/default-config.json | 1 + scripts/gcp-oidc/conf/prod-uid2-config.json | 3 ++- scripts/gcp/conf/integ-config.json | 1 + scripts/gcp/conf/prod-config.json | 1 + 15 files changed, 17 insertions(+), 2 deletions(-) diff --git a/conf/docker-config.json b/conf/docker-config.json index ab658e513..e6c277d48 100644 --- a/conf/docker-config.json +++ b/conf/docker-config.json @@ -33,6 +33,7 @@ "services_metadata_path": "/com.uid2.core/test/services/metadata.json", "service_links_metadata_path": "/com.uid2.core/test/service_links/metadata.json", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "optout_metadata_path": null, "optout_inmem_cache": false, "enclave_platform": null, diff --git a/conf/local-config.json b/conf/local-config.json index e8d7922a8..1dc5e5eef 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -10,6 +10,7 @@ "services_metadata_path": "/com.uid2.core/test/services/metadata.json", "service_links_metadata_path": "/com.uid2.core/test/service_links/metadata.json", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-docker-private-config.json b/conf/local-e2e-docker-private-config.json index 20b2ebb1a..6c30c5e6c 100644 --- a/conf/local-e2e-docker-private-config.json +++ b/conf/local-e2e-docker-private-config.json @@ -12,6 +12,7 @@ "keyset_keys_metadata_path": "http://core:8088/key/keyset-keys/refresh", "salts_metadata_path": "http://core:8088/salt/refresh", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index b3157b064..19e189913 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -14,6 +14,7 @@ "services_metadata_path": "http://core:8088/services/refresh", "service_links_metadata_path": "http://core:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index e09749d47..7b37b09fc 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -14,6 +14,7 @@ "services_metadata_path": "http://localhost:8088/services/refresh", "service_links_metadata_path": "http://localhost:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index 8c24e17bf..21a274699 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -14,6 +14,7 @@ "services_metadata_path": "http://localhost:8088/services/refresh", "service_links_metadata_path": "http://localhost:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/validator-latest-e2e-docker-public-config.json b/conf/validator-latest-e2e-docker-public-config.json index 87b042c7b..2c37a11b3 100644 --- a/conf/validator-latest-e2e-docker-public-config.json +++ b/conf/validator-latest-e2e-docker-public-config.json @@ -15,6 +15,7 @@ "services_metadata_path": "http://core:8088/services/refresh", "service_links_metadata_path": "http://core:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, + "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/scripts/aws/conf/prod-euid-config.json b/scripts/aws/conf/prod-euid-config.json index c7784a381..486837ede 100644 --- a/scripts/aws/conf/prod-euid-config.json +++ b/scripts/aws/conf/prod-euid-config.json @@ -20,6 +20,7 @@ "optout_inmem_cache": true, "optout_s3_folder": "optout/", "identity_token_expires_after_seconds": 259200, + "max_bidstream_lifetime_seconds": 259210, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/aws/conf/prod-uid2-config.json b/scripts/aws/conf/prod-uid2-config.json index 5da450033..d1159dde0 100644 --- a/scripts/aws/conf/prod-uid2-config.json +++ b/scripts/aws/conf/prod-uid2-config.json @@ -20,6 +20,7 @@ "optout_inmem_cache": true, "optout_s3_folder": "optout-v2/", "identity_token_expires_after_seconds": 259200, + "max_bidstream_lifetime_seconds": 259210, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index ca85949b2..d651adcab 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -32,6 +32,7 @@ "enclave_platform": "azure-cc", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 86400, + "max_bidstream_lifetime_seconds": 86410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/azure-cc/conf/prod-uid2-config.json b/scripts/azure-cc/conf/prod-uid2-config.json index 02e2cde20..acb3525bc 100644 --- a/scripts/azure-cc/conf/prod-uid2-config.json +++ b/scripts/azure-cc/conf/prod-uid2-config.json @@ -11,5 +11,6 @@ "core_attest_url": "https://core-prod.uidapi.com/attest", "optout_api_uri": "https://optout-prod.uidapi.com/optout/replicate", "optout_s3_folder": "optout-v2/", - "identity_token_expires_after_seconds": 259200 + "identity_token_expires_after_seconds": 259200, + "max_bidstream_lifetime_seconds": 259210 } diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index 209d677bf..f5cc320c3 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -32,6 +32,7 @@ "enclave_platform": "gcp-oidc", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 86400, + "max_bidstream_lifetime_seconds": 86410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/gcp-oidc/conf/prod-uid2-config.json b/scripts/gcp-oidc/conf/prod-uid2-config.json index f5445a9ec..b8612861a 100644 --- a/scripts/gcp-oidc/conf/prod-uid2-config.json +++ b/scripts/gcp-oidc/conf/prod-uid2-config.json @@ -11,5 +11,6 @@ "core_attest_url": "https://core.uidapi.com/attest", "optout_api_uri": "https://optout.uidapi.com/optout/replicate", "optout_s3_folder": "optout-v2/", - "identity_token_expires_after_seconds": 259200 + "identity_token_expires_after_seconds": 259200, + "max_bidstream_lifetime_seconds": 259210 } diff --git a/scripts/gcp/conf/integ-config.json b/scripts/gcp/conf/integ-config.json index 5bc91520c..36d85a1e6 100644 --- a/scripts/gcp/conf/integ-config.json +++ b/scripts/gcp/conf/integ-config.json @@ -9,6 +9,7 @@ "optout_s3_folder": "optout-v2/", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 14400, + "max_bidstream_lifetime_seconds": 14410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", diff --git a/scripts/gcp/conf/prod-config.json b/scripts/gcp/conf/prod-config.json index 09d7e760a..5db161d77 100644 --- a/scripts/gcp/conf/prod-config.json +++ b/scripts/gcp/conf/prod-config.json @@ -9,6 +9,7 @@ "optout_s3_folder": "optout-v2/", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 14400, + "max_bidstream_lifetime_seconds": 14410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", From 00f63a5f658f8b51d44cff921b4a6c4e1c5ddc59 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Fri, 8 Mar 2024 15:03:59 -0800 Subject: [PATCH 0217/1116] Address comments and add one more unit test --- .../operator/vertx/UIDOperatorVerticle.java | 18 ++++---- .../operator/ExtendedUIDOperatorVerticle.java | 8 +++- .../operator/UIDOperatorVerticleTest.java | 43 ++++++++++++++++++- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index b995b8d9d..81babd783 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -108,8 +108,8 @@ public class UIDOperatorVerticle extends AbstractVerticle { public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); protected boolean keySharingEndpointProvideSiteDomainNames; - private Map> siteIdToInvalidOrigins; - protected Instant lastInvalidOriginProcessTime; + protected Map> siteIdToInvalidOrigins = new HashMap<>(); + protected Instant lastInvalidOriginProcessTime = Instant.now(); public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, @@ -147,8 +147,6 @@ public UIDOperatorVerticle(JsonObject config, this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; - this.lastInvalidOriginProcessTime = Instant.now(); - this.siteIdToInvalidOrigins = new HashMap<>(); this.clientSideTokenGenerateLogInvalidHttpOrigin = config.getBoolean("client_side_token_generate_log_invalid_http_origins", false); } @@ -1781,23 +1779,23 @@ private void handleInvalidHttpOriginError(int siteId, String origin) { private String generateInvalidHttpOriginMessage(Map> siteIdToInvalidOrigins) { StringBuilder invalidHttpOriginMessage = new StringBuilder(); invalidHttpOriginMessage.append("InvalidHttpOrigin: "); - boolean mapHasFirstEle = false; + boolean mapHasFirstElement = false; for (Map.Entry> entry : siteIdToInvalidOrigins.entrySet()) { - if(mapHasFirstEle) { + if(mapHasFirstElement) { invalidHttpOriginMessage.append(" | "); } - mapHasFirstEle = true; + mapHasFirstElement = true; int siteId = entry.getKey(); Set origins = entry.getValue(); String siteName = getSiteName(siteProvider, siteId); String site = "site " + siteName + " (" + siteId + "): "; invalidHttpOriginMessage.append(site); - boolean setHasFirstEle = false; + boolean setHasFirstElement = false; for (String origin : origins) { - if(setHasFirstEle) { + if(setHasFirstElement) { invalidHttpOriginMessage.append(", "); } - setHasFirstEle = true; + setHasFirstElement = true; invalidHttpOriginMessage.append(origin); } } diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index d32e01849..8b585d9ff 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -11,6 +11,8 @@ import java.time.Clock; import java.time.Instant; +import java.util.Map; +import java.util.Set; //An extended UIDOperatorVerticle to expose classes for testing purposes public class ExtendedUIDOperatorVerticle extends UIDOperatorVerticle { @@ -36,7 +38,11 @@ public void setKeySharingEndpointProvideSiteDomainNames(boolean enable) { this.keySharingEndpointProvideSiteDomainNames = enable; } - public void setlastInvalidOriginProcessTime(Instant lastInvalidOriginProcessTime) { + public void setLastInvalidOriginProcessTime(Instant lastInvalidOriginProcessTime) { this.lastInvalidOriginProcessTime = lastInvalidOriginProcessTime; } + + public void setSiteIdToInvalidOrigins(Map> siteIdToInvalidOrigins) { + this.siteIdToInvalidOrigins = siteIdToInvalidOrigins; + } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index c2ac63e5c..81e4b392f 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -2737,7 +2737,7 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagI ListAppender logWatcher = new ListAppender<>(); logWatcher.start(); ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); - this.uidOperatorVerticle.setlastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); + this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); setupCstgBackend(); Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); @@ -2761,6 +2761,47 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagI }); } + @ParameterizedTest + @CsvSource({ + "true,http://gototest.com", + "false,http://gototest.com", + }) + void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(boolean setOptoutCheckFlagInRequest, String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); + this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); + + Map> siteIdToInvalidOrigins = new HashMap<>(); + siteIdToInvalidOrigins.put(clientSideTokenGenerateSiteId, new HashSet<>(Arrays.asList("http://localhost1.com", "http://localhost2.com"))); + siteIdToInvalidOrigins.put(124, new HashSet<>(Arrays.asList("http://xyz1.com", "http://xyz2.com"))); + + this.uidOperatorVerticle.setSiteIdToInvalidOrigins(siteIdToInvalidOrigins); + + setupCstgBackend(); + when(siteProvider.getSite(124)).thenReturn(new Site(124, "test2", true, new HashSet<>())); + + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); + sendCstg(vertx, + "v2/token/client-generate", + httpOrigin, + data.getItem1(), + data.getItem2(), + 403, + testContext, + respJson -> { + assertFalse(respJson.containsKey("body")); + assertEquals("unexpected http origin", respJson.getString("message")); + assertEquals("invalid_http_origin", respJson.getString("status")); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOrigin: site test (123): http://localhost1.com, http://gototest.com, http://localhost2.com | site test2 (124): http://xyz1.com, http://xyz2.com")); + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin); + testContext.completeNow(); + }); + } + @ParameterizedTest @CsvSource({ "true,https://cstg.co.uk", From a08a6590d1302975810e076e38ce7cf3681d9dd3 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 11 Mar 2024 10:55:45 +0800 Subject: [PATCH 0218/1116] Fixed secret key name for EUID --- scripts/aws/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 1c735b1f5..87be7d8a0 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -21,7 +21,7 @@ if [ "${IDENTITY_SCOPE}" = "UID2" ]; then OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) - UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") + UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") else From c2961bd135dac90b5a46e8b5a1e04d48260bc302 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 11 Mar 2024 03:00:15 +0000 Subject: [PATCH 0219/1116] Released Snapshot version: 5.27.56-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f79d73763..b5148a2d0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.44-51b2f952f3 + 5.27.56-SNAPSHOT UTF-8 From 3712a7083cfb63d1324c46a66697e9bb9999eefc Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 11 Mar 2024 11:48:38 +0800 Subject: [PATCH 0220/1116] Added identity scope to E2E test pipeline title --- .github/workflows/run-e2e-tests-on-operator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 7de009f88..13c4e5569 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -1,5 +1,5 @@ name: Run Operator E2E Tests -run-name: ${{ format('Run Operator E2E Tests - {0}', inputs.operator_type) }} by @${{ github.actor }} +run-name: ${{ format('Run Operator E2E Tests - {0} {1}', inputs.operator_type, inputs.identity_scope) }} by @${{ github.actor }} on: workflow_dispatch: inputs: From 1af36277e4c5ec31510fa43ad2ba20619bacf17b Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 11 Mar 2024 12:10:06 +0800 Subject: [PATCH 0221/1116] Fixed EUID entrypoint.sh --- scripts/aws/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 87be7d8a0..91560167e 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -21,7 +21,7 @@ if [ "${IDENTITY_SCOPE}" = "UID2" ]; then OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) - UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") + UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") else From 17c99957fd5eb824ac9a5bdab9f59c8d6c8aa49d Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 11 Mar 2024 04:12:26 +0000 Subject: [PATCH 0222/1116] Released Snapshot version: 5.27.59-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b5148a2d0..d30df1e25 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.56-SNAPSHOT + 5.27.59-SNAPSHOT UTF-8 From ec6aff320bacdea4fdb4707a1d9048d461c0aa65 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Mon, 11 Mar 2024 13:27:35 +0800 Subject: [PATCH 0223/1116] Updated core/optout URL replace for EUID --- scripts/aws/entrypoint.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 91560167e..956bde9ac 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -90,10 +90,16 @@ function jq_inplace_update_json() { # -- using hardcoded domains is fine because they should not be changed frequently if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..." + sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" sed -i "s#https://core-prod.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://core.integ.euid.eu#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://core.prod.euid.eu#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" sed -i "s#https://optout-prod.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout.integ.euid.eu#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout.prod.euid.eu#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" fi cat "${FINAL_CONFIG}" From 190a60879ed9657f2ad36e834de956317d16935d Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 11 Mar 2024 05:30:06 +0000 Subject: [PATCH 0224/1116] Released Snapshot version: 5.27.61-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d30df1e25..9664f0813 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.59-SNAPSHOT + 5.27.61-SNAPSHOT UTF-8 From 252d35b53bba3b8186f273014a972a82954ffd39 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 10:42:53 +1100 Subject: [PATCH 0225/1116] Add example JSON to addSites --- .../operator/vertx/UIDOperatorVerticle.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index e9a7ca7fe..981950889 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -594,6 +594,26 @@ private void addBidstreamHeaderFields(JsonObject resp) { private void addSites(JsonObject resp, List keys, Map keysetMap) { final List sites = getSitesWithDomainNames(keys, keysetMap); if (sites != null) { + /* + The end result will look something like this: + + "site_data": [ + { + "id": 101, + "domain_names": [ + "101.co.uk", + "101.com" + ] + }, + { + "id": 102, + "domain_names": [ + "102.co.uk", + "102.com" + ] + } + ] + */ final List sitesJson = sites.stream() .map(UIDOperatorVerticle::toJson) .collect(Collectors.toList()); From 55f0166d0e02deb991068216f0cdf6d4de918261 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 10:44:54 +1100 Subject: [PATCH 0226/1116] Rename SharingEndpoint to KeyDownloadEndpoint --- .../operator/UIDOperatorVerticleTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 467e74d18..92fe9b0d6 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -403,7 +403,7 @@ private void checkEncryptionKeysResponse(JsonObject response, KeysetKey... expec } } - private void checkEncryptionKeys(JsonObject response, SharingEndpoint endpoint, int callersSiteId, KeysetKey... expectedKeys) { + private void checkEncryptionKeys(JsonObject response, KeyDownloadEndpoint endpoint, int callersSiteId, KeysetKey... expectedKeys) { assertEquals("success", response.getString("status")); final JsonArray responseKeys = response.getJsonObject("body").getJsonArray("keys"); assertNotNull(responseKeys); @@ -442,13 +442,13 @@ private void checkEncryptionKeys(JsonObject response, SharingEndpoint endpoint, } } - private enum SharingEndpoint { + private enum KeyDownloadEndpoint { SHARING("/key/sharing"), BIDSTREAM("/key/bidstream"); private String path; - SharingEndpoint(String path) { + KeyDownloadEndpoint(String path) { this.path = path; } @@ -3913,7 +3913,7 @@ void keySharingKeysets_CorrectFiltering(Vertx vertx, VertxTestContext testContex send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { System.out.println(respJson); - checkEncryptionKeys(respJson, SharingEndpoint.SHARING, siteId, expectedKeys); + checkEncryptionKeys(respJson, KeyDownloadEndpoint.SHARING, siteId, expectedKeys); testContext.completeNow(); }); } @@ -3970,7 +3970,7 @@ public void verifyExpectedSiteDetail(HashMap> expectedSite // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, SharingEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { + void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { if (!provideSiteDomainNames) { this.uidOperatorVerticle.setKeySharingEndpointProvideSiteDomainNames(false); @@ -4094,7 +4094,7 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int exp assertEquals(getIdentityScope().toString(), respJson.getJsonObject("body").getString("identity_scope")); assertNotNull(respJson.getJsonObject("body").getInteger("allow_clock_skew_seconds")); - checkEncryptionKeys(respJson, SharingEndpoint.SHARING, clientSiteId, expectedKeys); + checkEncryptionKeys(respJson, KeyDownloadEndpoint.SHARING, clientSiteId, expectedKeys); HashMap> expectedSites = setupExpectation(101, 104); verifyExpectedSiteDetail(expectedSites, respJson.getJsonObject("body").getJsonArray("site_data")); @@ -4122,7 +4122,7 @@ void keySharingKeysets_ReturnsMasterAndSite(Vertx vertx, VertxTestContext testCo send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { System.out.println(respJson); verifyExpectedSiteDetail(new HashMap<>(), respJson.getJsonObject("body").getJsonArray("site_data")); - checkEncryptionKeys(respJson, SharingEndpoint.SHARING, siteId, encryptionKeys); + checkEncryptionKeys(respJson, KeyDownloadEndpoint.SHARING, siteId, encryptionKeys); testContext.completeNow(); }); } @@ -4196,7 +4196,7 @@ void keySharingKeysets_CorrectIDS(String testRun, Vertx vertx, VertxTestContext verifyExpectedSiteDetail(expectedSites, siteData); break; } - checkEncryptionKeys(respJson, SharingEndpoint.SHARING, clientSiteId, expectedKeys); + checkEncryptionKeys(respJson, KeyDownloadEndpoint.SHARING, clientSiteId, expectedKeys); testContext.completeNow(); }); } @@ -4205,7 +4205,7 @@ private static List keySharingRotatingKeysets_IDREADER_source() { final String[] testRuns = {"KeysetAccess", "AddKeyset", "AddKey", "RotateKey", "DisableKey", "DisableKeyset"}; final List arguments = new ArrayList<>(); - for (SharingEndpoint endpoint : SharingEndpoint.values()) { + for (KeyDownloadEndpoint endpoint : KeyDownloadEndpoint.values()) { for (String testRun : testRuns) { arguments.add(Arguments.of(testRun, endpoint)); } @@ -4222,7 +4222,7 @@ private static List keySharingRotatingKeysets_IDREADER_source() { // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingRotatingKeysets_IDREADER(String testRun, SharingEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { + void keySharingRotatingKeysets_IDREADER(String testRun, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { String apiVersion = "v2"; int clientSiteId = 101; fakeAuth(clientSiteId, Role.ID_READER); @@ -4324,7 +4324,7 @@ void keySharingRotatingKeysets_IDREADER(String testRun, SharingEndpoint endpoint }); } - private void checkSharingResponseHeaderFields(SharingEndpoint endpoint, JsonObject body, int clientSiteId) { + private void checkSharingResponseHeaderFields(KeyDownloadEndpoint endpoint, JsonObject body, int clientSiteId) { assertEquals(this.getIdentityScope().toString(), body.getString("identity_scope")); assertEquals(config.getInteger(Const.Config.AllowClockSkewSecondsProp), body.getInteger("allow_clock_skew_seconds")); From e2481fff75304c7cb6f12836cd12a6c738fa5b6e Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 10:48:10 +1100 Subject: [PATCH 0227/1116] Rename checkSharingResponseHeaderFields to checkKeyDownloadResponseHeaderFields --- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 92fe9b0d6..3a8584124 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4018,7 +4018,7 @@ void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, KeyDownloadEndpo final JsonObject body = respJson.getJsonObject("body"); - checkSharingResponseHeaderFields(endpoint, body, clientSiteId); + checkKeyDownloadResponseHeaderFields(endpoint, body, clientSiteId); checkEncryptionKeys(respJson, endpoint, clientSiteId, expectedKeys); @@ -4317,14 +4317,14 @@ void keySharingRotatingKeysets_IDREADER(String testRun, KeyDownloadEndpoint endp assertEquals("success", respJson.getString("status")); final JsonObject body = respJson.getJsonObject("body"); - checkSharingResponseHeaderFields(endpoint, body, clientSiteId); + checkKeyDownloadResponseHeaderFields(endpoint, body, clientSiteId); checkEncryptionKeys(respJson, endpoint, clientSiteId, expectedKeys.toArray(new KeysetKey[0])); testContext.completeNow(); }); } - private void checkSharingResponseHeaderFields(KeyDownloadEndpoint endpoint, JsonObject body, int clientSiteId) { + private void checkKeyDownloadResponseHeaderFields(KeyDownloadEndpoint endpoint, JsonObject body, int clientSiteId) { assertEquals(this.getIdentityScope().toString(), body.getString("identity_scope")); assertEquals(config.getInteger(Const.Config.AllowClockSkewSecondsProp), body.getInteger("allow_clock_skew_seconds")); From 81abc28ddd54e3f78198654ea84ae77f7f5c96ab Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 11:46:36 +1100 Subject: [PATCH 0228/1116] Revert "Add max_sharing_lifetime_seconds to config files" This reverts commit 65470170b493b272eb8ae47931d3c8ee50f0a5c6. --- conf/default-config.json | 3 +-- conf/local-config.json | 1 - conf/local-e2e-private-config.json | 1 - conf/local-e2e-public-config.json | 1 - scripts/aws/conf/default-config.json | 1 - scripts/azure-cc/conf/default-config.json | 1 - scripts/gcp-oidc/conf/default-config.json | 1 - scripts/gcp/conf/integ-config.json | 3 +-- scripts/gcp/conf/prod-config.json | 3 +-- 9 files changed, 3 insertions(+), 12 deletions(-) diff --git a/conf/default-config.json b/conf/default-config.json index 77cdf571d..6469529e9 100644 --- a/conf/default-config.json +++ b/conf/default-config.json @@ -32,6 +32,5 @@ "optout_inmem_cache": false, "enclave_platform": null, "failure_shutdown_wait_hours": 120, - "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010 + "sharing_token_expiry_seconds": 2592000 } diff --git a/conf/local-config.json b/conf/local-config.json index 7e673a6e7..244ed94da 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -20,7 +20,6 @@ "identity_scope": "uid2", "enable_v2_encryption": false, "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index b32843388..ab32d0d0f 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -23,7 +23,6 @@ "identity_scope": "uid2", "enable_v2_encryption": true, "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index ad07820e3..c36ff6094 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -23,7 +23,6 @@ "identity_scope": "uid2", "enable_v2_encryption": true, "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/scripts/aws/conf/default-config.json b/scripts/aws/conf/default-config.json index 352fcd45b..4146e55c0 100644 --- a/scripts/aws/conf/default-config.json +++ b/scripts/aws/conf/default-config.json @@ -33,7 +33,6 @@ "enclave_platform": null, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010, "validate_service_links": false, "advertising_token_v4_percentage": 0 } diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index d651adcab..8ace6bd1a 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -38,7 +38,6 @@ "allow_legacy_api": false, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010, "validate_service_links": false, "advertising_token_v4_percentage": 0 } diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index f5cc320c3..677827290 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -38,7 +38,6 @@ "allow_legacy_api": false, "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010, "validate_service_links": false, "advertising_token_v4_percentage": 0 } diff --git a/scripts/gcp/conf/integ-config.json b/scripts/gcp/conf/integ-config.json index 36d85a1e6..b16dfb9dc 100644 --- a/scripts/gcp/conf/integ-config.json +++ b/scripts/gcp/conf/integ-config.json @@ -15,6 +15,5 @@ "enclave_platform": "gcp-vmid", "service_instances": 16, "allow_legacy_api": false, - "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010 + "sharing_token_expiry_seconds": 2592000 } diff --git a/scripts/gcp/conf/prod-config.json b/scripts/gcp/conf/prod-config.json index 5db161d77..7eeffcd7b 100644 --- a/scripts/gcp/conf/prod-config.json +++ b/scripts/gcp/conf/prod-config.json @@ -15,6 +15,5 @@ "enclave_platform": "gcp-vmid", "service_instances": 16, "allow_legacy_api": false, - "sharing_token_expiry_seconds": 2592000, - "max_sharing_lifetime_seconds": 2592010 + "sharing_token_expiry_seconds": 2592000 } From c47a1c30ccc00b853236eaa14a2679829d10263f Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 11:46:42 +1100 Subject: [PATCH 0229/1116] Revert "Add max_bidstream_lifetime_seconds to config files" This reverts commit 8d0c35d2e2d843c6f96174fe60cb77e1378db812. --- conf/docker-config.json | 1 - conf/local-config.json | 1 - conf/local-e2e-docker-private-config.json | 1 - conf/local-e2e-docker-public-config.json | 1 - conf/local-e2e-private-config.json | 1 - conf/local-e2e-public-config.json | 1 - conf/validator-latest-e2e-docker-public-config.json | 1 - scripts/aws/conf/prod-euid-config.json | 1 - scripts/aws/conf/prod-uid2-config.json | 1 - scripts/azure-cc/conf/default-config.json | 1 - scripts/azure-cc/conf/prod-uid2-config.json | 3 +-- scripts/gcp-oidc/conf/default-config.json | 1 - scripts/gcp-oidc/conf/prod-uid2-config.json | 3 +-- scripts/gcp/conf/integ-config.json | 1 - scripts/gcp/conf/prod-config.json | 1 - 15 files changed, 2 insertions(+), 17 deletions(-) diff --git a/conf/docker-config.json b/conf/docker-config.json index e6c277d48..ab658e513 100644 --- a/conf/docker-config.json +++ b/conf/docker-config.json @@ -33,7 +33,6 @@ "services_metadata_path": "/com.uid2.core/test/services/metadata.json", "service_links_metadata_path": "/com.uid2.core/test/service_links/metadata.json", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "optout_metadata_path": null, "optout_inmem_cache": false, "enclave_platform": null, diff --git a/conf/local-config.json b/conf/local-config.json index 244ed94da..af46c8f61 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -10,7 +10,6 @@ "services_metadata_path": "/com.uid2.core/test/services/metadata.json", "service_links_metadata_path": "/com.uid2.core/test/service_links/metadata.json", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-docker-private-config.json b/conf/local-e2e-docker-private-config.json index b144ec078..947c2af3c 100644 --- a/conf/local-e2e-docker-private-config.json +++ b/conf/local-e2e-docker-private-config.json @@ -12,7 +12,6 @@ "keyset_keys_metadata_path": "http://core:8088/key/keyset-keys/refresh", "salts_metadata_path": "http://core:8088/salt/refresh", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index 9742fdc76..70eaa049e 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -14,7 +14,6 @@ "services_metadata_path": "http://core:8088/services/refresh", "service_links_metadata_path": "http://core:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index ab32d0d0f..32b65e691 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -14,7 +14,6 @@ "services_metadata_path": "http://localhost:8088/services/refresh", "service_links_metadata_path": "http://localhost:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index c36ff6094..a57f636aa 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -14,7 +14,6 @@ "services_metadata_path": "http://localhost:8088/services/refresh", "service_links_metadata_path": "http://localhost:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/conf/validator-latest-e2e-docker-public-config.json b/conf/validator-latest-e2e-docker-public-config.json index d407335d5..2b94970d2 100644 --- a/conf/validator-latest-e2e-docker-public-config.json +++ b/conf/validator-latest-e2e-docker-public-config.json @@ -15,7 +15,6 @@ "services_metadata_path": "http://core:8088/services/refresh", "service_links_metadata_path": "http://core:8088/service_links/refresh", "identity_token_expires_after_seconds": 3600, - "max_bidstream_lifetime_seconds": 3610, "refresh_token_expires_after_seconds": 86400, "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, diff --git a/scripts/aws/conf/prod-euid-config.json b/scripts/aws/conf/prod-euid-config.json index 486837ede..c7784a381 100644 --- a/scripts/aws/conf/prod-euid-config.json +++ b/scripts/aws/conf/prod-euid-config.json @@ -20,7 +20,6 @@ "optout_inmem_cache": true, "optout_s3_folder": "optout/", "identity_token_expires_after_seconds": 259200, - "max_bidstream_lifetime_seconds": 259210, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/aws/conf/prod-uid2-config.json b/scripts/aws/conf/prod-uid2-config.json index d1159dde0..5da450033 100644 --- a/scripts/aws/conf/prod-uid2-config.json +++ b/scripts/aws/conf/prod-uid2-config.json @@ -20,7 +20,6 @@ "optout_inmem_cache": true, "optout_s3_folder": "optout-v2/", "identity_token_expires_after_seconds": 259200, - "max_bidstream_lifetime_seconds": 259210, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index 8ace6bd1a..c0684b85f 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -32,7 +32,6 @@ "enclave_platform": "azure-cc", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 86400, - "max_bidstream_lifetime_seconds": 86410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/azure-cc/conf/prod-uid2-config.json b/scripts/azure-cc/conf/prod-uid2-config.json index acb3525bc..02e2cde20 100644 --- a/scripts/azure-cc/conf/prod-uid2-config.json +++ b/scripts/azure-cc/conf/prod-uid2-config.json @@ -11,6 +11,5 @@ "core_attest_url": "https://core-prod.uidapi.com/attest", "optout_api_uri": "https://optout-prod.uidapi.com/optout/replicate", "optout_s3_folder": "optout-v2/", - "identity_token_expires_after_seconds": 259200, - "max_bidstream_lifetime_seconds": 259210 + "identity_token_expires_after_seconds": 259200 } diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index 677827290..c744175a2 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -32,7 +32,6 @@ "enclave_platform": "gcp-oidc", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 86400, - "max_bidstream_lifetime_seconds": 86410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "allow_legacy_api": false, diff --git a/scripts/gcp-oidc/conf/prod-uid2-config.json b/scripts/gcp-oidc/conf/prod-uid2-config.json index b8612861a..f5445a9ec 100644 --- a/scripts/gcp-oidc/conf/prod-uid2-config.json +++ b/scripts/gcp-oidc/conf/prod-uid2-config.json @@ -11,6 +11,5 @@ "core_attest_url": "https://core.uidapi.com/attest", "optout_api_uri": "https://optout.uidapi.com/optout/replicate", "optout_s3_folder": "optout-v2/", - "identity_token_expires_after_seconds": 259200, - "max_bidstream_lifetime_seconds": 259210 + "identity_token_expires_after_seconds": 259200 } diff --git a/scripts/gcp/conf/integ-config.json b/scripts/gcp/conf/integ-config.json index b16dfb9dc..7223450e5 100644 --- a/scripts/gcp/conf/integ-config.json +++ b/scripts/gcp/conf/integ-config.json @@ -9,7 +9,6 @@ "optout_s3_folder": "optout-v2/", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 14400, - "max_bidstream_lifetime_seconds": 14410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", diff --git a/scripts/gcp/conf/prod-config.json b/scripts/gcp/conf/prod-config.json index 7eeffcd7b..17f85276b 100644 --- a/scripts/gcp/conf/prod-config.json +++ b/scripts/gcp/conf/prod-config.json @@ -9,7 +9,6 @@ "optout_s3_folder": "optout-v2/", "optout_inmem_cache": true, "identity_token_expires_after_seconds": 14400, - "max_bidstream_lifetime_seconds": 14410, "refresh_token_expires_after_seconds": 2592000, "refresh_identity_token_after_seconds": 3600, "enclave_platform": "gcp-vmid", From 1622ed01c445ea82a51148cc51e4e29c3f4bb7b9 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 15:06:34 +1100 Subject: [PATCH 0230/1116] Add tolerance to sharing and bidstream token lifetimes --- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 9 +++++++-- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 981950889..e9c59af56 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -72,6 +72,11 @@ public class UIDOperatorVerticle extends AbstractVerticle { private static final Logger LOGGER = LoggerFactory.getLogger(UIDOperatorVerticle.class); public static final long MAX_REQUEST_BODY_SIZE = 1 << 20; // 1MB + /** + * There is currently an issue with v2 tokens (and possibly also other ad token versions) where the token lifetime + * is slightly longer than it should be. When validating token lifetimes, we add a small buffer to account for this. + */ + public static final Duration TOKEN_LIFETIME_TOLERANCE = Duration.ofSeconds(10); private static final DateTimeFormatter APIDateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.of("UTC")); private static final String REQUEST = "request"; @@ -586,7 +591,7 @@ public void handleKeysBidstream(RoutingContext rc) { } private void addBidstreamHeaderFields(JsonObject resp) { - resp.put("max_bidstream_lifetime_seconds", maxBidstreamLifetimeSeconds); + resp.put("max_bidstream_lifetime_seconds", maxBidstreamLifetimeSeconds + TOKEN_LIFETIME_TOLERANCE.toSeconds()); addIdentityScopeField(resp); addAllowClockSkewSecondsField(resp); } @@ -639,7 +644,7 @@ private void addSharingHeaderFields(JsonObject resp, KeyManagerSnapshot keyManag resp.put("token_expiry_seconds", getSharingTokenExpirySeconds()); if (clientKey.hasRole(Role.SHARER)) { - resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds); + resp.put("max_sharing_lifetime_seconds", maxSharingLifetimeSeconds + TOKEN_LIFETIME_TOLERANCE.toSeconds()); } addIdentityScopeField(resp); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 3a8584124..41d87ca9d 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -70,6 +70,7 @@ import static com.uid2.operator.IdentityConst.*; import static com.uid2.operator.service.EncodingUtils.getSha256; import static com.uid2.operator.vertx.UIDOperatorVerticle.OPT_OUT_CHECK_CUTOFF_DATE; +import static com.uid2.operator.vertx.UIDOperatorVerticle.TOKEN_LIFETIME_TOLERANCE; import static com.uid2.shared.Const.Data.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; @@ -4090,7 +4091,7 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int exp assertEquals(4, respJson.getJsonObject("body").getInteger("default_keyset_id")); assertEquals(config.getInteger(Const.Config.SharingTokenExpiryProp), Integer.parseInt(respJson.getJsonObject("body").getString("token_expiry_seconds"))); - assertEquals(expectedMaxSharingLifetimeSeconds, respJson.getJsonObject("body").getInteger("max_sharing_lifetime_seconds")); + assertEquals(expectedMaxSharingLifetimeSeconds + TOKEN_LIFETIME_TOLERANCE.toSeconds(), respJson.getJsonObject("body").getLong("max_sharing_lifetime_seconds")); assertEquals(getIdentityScope().toString(), respJson.getJsonObject("body").getString("identity_scope")); assertNotNull(respJson.getJsonObject("body").getInteger("allow_clock_skew_seconds")); @@ -4340,7 +4341,7 @@ private void checkKeyDownloadResponseHeaderFields(KeyDownloadEndpoint endpoint, assertFalse(body.containsKey("max_bidstream_lifetime_seconds")); break; case BIDSTREAM: - assertEquals(config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp), body.getInteger("max_bidstream_lifetime_seconds")); + assertEquals(config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp) + TOKEN_LIFETIME_TOLERANCE.toSeconds(), body.getLong("max_bidstream_lifetime_seconds")); // Check that /key/sharing header fields are not present. assertFalse(body.containsKey("caller_site_id")); From 938b75518128916746c3d88e8c7c167c036b035e Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 12 Mar 2024 15:13:54 +1100 Subject: [PATCH 0231/1116] Rename keySharingRotatingKeysets_IDREADER_source to keyDownloadEndpointRotatingKeysets_IDREADER_source --- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 41d87ca9d..f810e7cf8 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4202,7 +4202,7 @@ void keySharingKeysets_CorrectIDS(String testRun, Vertx vertx, VertxTestContext }); } - private static List keySharingRotatingKeysets_IDREADER_source() { + private static List keyDownloadEndpointRotatingKeysets_IDREADER_source() { final String[] testRuns = {"KeysetAccess", "AddKeyset", "AddKey", "RotateKey", "DisableKey", "DisableKeyset"}; final List arguments = new ArrayList<>(); @@ -4215,7 +4215,9 @@ private static List keySharingRotatingKeysets_IDREADER_source() { } @ParameterizedTest - @MethodSource("keySharingRotatingKeysets_IDREADER_source") + @MethodSource("keyDownloadEndpointRotatingKeysets_IDREADER_source") + // Test the /key/sharing and /key/bidstream endpoints when called with the ID_READER role. + // // "KeysetAccess" // ID_READER has access to a keyset that has the same site_id as ID_READER's - direct access // ID_READER has access to a keyset with a missing allowed_sites - access through sharing @@ -4223,7 +4225,7 @@ private static List keySharingRotatingKeysets_IDREADER_source() { // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingRotatingKeysets_IDREADER(String testRun, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { + void keyDownloadEndpointRotatingKeysets_IDREADER(String testRun, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { String apiVersion = "v2"; int clientSiteId = 101; fakeAuth(clientSiteId, Role.ID_READER); From 54a890a2a31a5a52c1ba3d9ce0fda3564cbe752d Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 12 Mar 2024 14:11:14 +0800 Subject: [PATCH 0232/1116] Optimised redundant code in if-condition --- scripts/aws/entrypoint.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 1c735b1f5..795b50e4a 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -14,20 +14,18 @@ echo "Starting vsock proxy..." # -- load env vars via proxy echo "Loading env vars via proxy..." +USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) if [ "${IDENTITY_SCOPE}" = "UID2" ]; then - USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") - CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") - OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then - USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") - CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") - OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") else echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" exit 1 fi +CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") +OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") + echo "UID2_CONFIG_SECRET_KEY=${UID2_CONFIG_SECRET_KEY}" echo "CORE_BASE_URL=${CORE_BASE_URL}" echo "OPTOUT_BASE_URL=${OPTOUT_BASE_URL}" From 7eac79cbc606808e32f959a7eca9d628a9e5f3ee Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 12 Mar 2024 16:14:05 +0800 Subject: [PATCH 0233/1116] Added AWS operator pipeline in Publish All Operators --- .github/workflows/publish-all-operators.yaml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index c34216374..627753478 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -97,10 +97,19 @@ jobs: vulnerability_severity: ${{ inputs.vulnerability_severity }} secrets: inherit + buildAWS: + name: AWS Private Operator + needs: start + uses: ./.github/workflows/publish-aws-nitro-enclave-docker.yaml + with: + release_type: ${{ inputs.release_type }} + version_number_input: ${{ needs.start.outputs.new_version }} + secrets: inherit + collectAllArtifacts: name: Collect All Artifacts runs-on: ubuntu-latest - needs: [start, buildPublic, buildGCP, buildAzure] + needs: [start, buildPublic, buildGCP, buildAzure, buildAWS] steps: - name: Download public artifacts uses: actions/download-artifact@v4 @@ -120,6 +129,12 @@ jobs: name: azure-cc-deployment-files path: ./artifacts/azure_cc_operator + - name: Download AWS artifacts + uses: actions/download-artifact@v4 + with: + name: aws-nitro-deployment-files + path: ./artifacts/aws_nitro_operator + - name: Delete staging artifacts uses: geekyeggo/delete-artifact@v4 with: @@ -127,6 +142,7 @@ jobs: image-details gcp-oidc-deployment-files azure-cc-deployment-files + aws-nitro-deployment-files - name: Upload artifacts uses: actions/upload-artifact@v4 @@ -154,7 +170,7 @@ jobs: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.meta.outputs.tags }}\n```\n\n## TODO\nPlease upload the zipped AWS artifacts to this draft. (version_number_input: ${{ needs.start.outputs.new_version }})\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.meta.outputs.tags }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: From 1efd4072b63d8c6f15c52976f6766d659fc9bcc3 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Tue, 12 Mar 2024 16:19:12 +0800 Subject: [PATCH 0234/1116] Added release creation for AWS pipeline --- .../publish-aws-nitro-enclave-docker.yaml | 31 ++++++++++++++++++- .../publish-azure-cc-enclave-docker.yaml | 8 ++--- .../publish-gcp-oidc-enclave-docker.yaml | 8 ++--- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 16d112132..b26bc365e 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -127,8 +127,37 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} - - uses: actions/upload-artifact@v3 + - name: Archive deployment artifacts + uses: actions/upload-artifact@v4 with: name: aws-nitro-deployment-files path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} if-no-files-found: error + + - name: Generate release archive + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + run: | + zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* + + - name: Build changelog + id: github_release + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + uses: mikepenz/release-changelog-builder-action@v4 + with: + configurationJson: | + { + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.updatePom.outputs.image_tag }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" + } + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create release + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + uses: softprops/action-gh-release@v1 + with: + name: ${{ steps.version.outputs.new_version }} + body: ${{ steps.github_release.outputs.changelog }} + draft: true + files: | + ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 96fee4414..de9b262bd 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -217,15 +217,15 @@ jobs: uses: actions/upload-artifact@v4 with: name: azure-cc-deployment-files - path: | - ${{ env.ARTIFACTS_OUTPUT_DIR }} + path: ${{ env.ARTIFACTS_OUTPUT_DIR }} + if-no-files-found: error - name: Generate release archive if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - - name: Build Changelog + - name: Build changelog id: github_release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v4 @@ -238,7 +238,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Create Release + - name: Create release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v1 with: diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index b432f3043..67f34354e 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -253,15 +253,15 @@ jobs: uses: actions/upload-artifact@v4 with: name: gcp-oidc-deployment-files - path: | - ${{ env.ARTIFACTS_OUTPUT_DIR }} + path: ${{ env.ARTIFACTS_OUTPUT_DIR }} + if-no-files-found: error - name: Generate release archive if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - - name: Build Changelog + - name: Build changelog id: github_release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v4 @@ -274,7 +274,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Create Release + - name: Create release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v1 with: From 542ec25caee085d39781524aaf15e002980c8e5a Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 13 Mar 2024 09:05:02 +1100 Subject: [PATCH 0235/1116] Add test for custom max bidstream lifetime config value --- .../operator/UIDOperatorVerticleTest.java | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index f810e7cf8..357732575 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -110,7 +110,7 @@ public class UIDOperatorVerticleTest { private SimpleMeterRegistry registry; private ExtendedUIDOperatorVerticle uidOperatorVerticle; - private JsonObject config; + private final JsonObject config = new JsonObject(); @BeforeEach public void deployVerticle(Vertx vertx, VertxTestContext testContext, TestInfo testInfo) { @@ -119,8 +119,6 @@ public void deployVerticle(Vertx vertx, VertxTestContext testContext, TestInfo t when(clock.instant()).thenAnswer(i -> now); when(this.secureLinkValidatorService.validateRequest(any(RoutingContext.class), any(JsonObject.class), any(Role.class))).thenReturn(true); - - config = new JsonObject(); setupConfig(config); if(testInfo.getDisplayName().equals("cstgNoPhoneSupport(Vertx, VertxTestContext)")) { config.put("enable_phone_support", false); @@ -157,7 +155,6 @@ private void setupConfig(JsonObject config) { config.put("client_side_token_generate_log_invalid_http_origins", true); config.put(Const.Config.AllowClockSkewSecondsProp, 3600); - config.put(Const.Config.MaxBidstreamLifetimeSecondsProp, identityExpiresAfter.toSeconds() + 10); } private static byte[] makeAesKey(String prefix) { @@ -3957,6 +3954,37 @@ public void verifyExpectedSiteDetail(HashMap> expectedSite } } + @Nested + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + public class keyBidstreamCustomMaxBidstreamLifetime { + // The @BeforeAll annotation will let setupConfig run before the outer class's @BeforeEach, allowing us to + // customise the verticle config before it is deployed. + @BeforeAll + public void setupConfig() { + UIDOperatorVerticleTest.this.config.put(Const.Config.MaxBidstreamLifetimeSecondsProp, 9999); + } + + @Test + public void keyBidstreamReturnsCustomMaxBidstreamLifetimeHeader(Vertx vertx, VertxTestContext testContext) { + final String apiVersion = "v2"; + final KeyDownloadEndpoint endpoint = KeyDownloadEndpoint.BIDSTREAM; + + final int clientSiteId = 101; + fakeAuth(clientSiteId, Role.ID_READER); + + // Required, sets up mock keys. + new MultipleKeysetsTests(); + + send(apiVersion, vertx, apiVersion + endpoint.getPath(), true, null, null, 200, respJson -> { + assertEquals("success", respJson.getString("status")); + + checkKeyDownloadResponseHeaderFields(endpoint, respJson.getJsonObject("body"), clientSiteId); + + testContext.completeNow(); + }); + } + } + @ParameterizedTest @CsvSource({ "true, SHARING", @@ -4343,7 +4371,8 @@ private void checkKeyDownloadResponseHeaderFields(KeyDownloadEndpoint endpoint, assertFalse(body.containsKey("max_bidstream_lifetime_seconds")); break; case BIDSTREAM: - assertEquals(config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp) + TOKEN_LIFETIME_TOLERANCE.toSeconds(), body.getLong("max_bidstream_lifetime_seconds")); + final int expectedMaxBidstreamLifetimeSeconds = config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp, config.getInteger(UIDOperatorService.IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS)); + assertEquals(expectedMaxBidstreamLifetimeSeconds + TOKEN_LIFETIME_TOLERANCE.toSeconds(), body.getLong("max_bidstream_lifetime_seconds")); // Check that /key/sharing header fields are not present. assertFalse(body.containsKey("caller_site_id")); From d50d0b0e1c0dccee05191c87c93b9aa62f30135b Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 13 Mar 2024 09:15:06 +1100 Subject: [PATCH 0236/1116] Rename keySharingKeysets_IDREADER to keyDownloadEndpointKeysets_IDREADER --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 357732575..27abea113 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -3992,6 +3992,8 @@ public void keyBidstreamReturnsCustomMaxBidstreamLifetimeHeader(Vertx vertx, Ver "true, BIDSTREAM", "false, BIDSTREAM", }) + // Test the /key/sharing and /key/bidstream endpoints when called with the ID_READER role. + // // Tests: // ID_READER has access to a keyset that has the same site_id as ID_READER's - direct access // ID_READER has access to a keyset with a missing allowed_sites - access through sharing @@ -3999,7 +4001,7 @@ public void keyBidstreamReturnsCustomMaxBidstreamLifetimeHeader(Vertx vertx, Ver // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingKeysets_IDREADER(boolean provideSiteDomainNames, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { + void keyDownloadEndpointKeysets_IDREADER(boolean provideSiteDomainNames, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { if (!provideSiteDomainNames) { this.uidOperatorVerticle.setKeySharingEndpointProvideSiteDomainNames(false); From edaab4c048e685898d32bdd1d16edbea689285be Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Wed, 13 Mar 2024 09:21:08 +1100 Subject: [PATCH 0237/1116] Assert equality on JSON objects, instead of field-by-field This means we can't miss asserts on fields, or include unexpected fields in the response. For example this would have caught the issue with serializing token_expiry_seconds as a string (we had no tests for that). --- .../operator/UIDOperatorVerticleTest.java | 112 ++++++++---------- 1 file changed, 51 insertions(+), 61 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 27abea113..5bbb03bfa 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -384,60 +384,53 @@ private void postV2(ClientKey ck, Vertx vertx, String endpoint, JsonObject body, private void checkEncryptionKeysResponse(JsonObject response, KeysetKey... expectedKeys) { assertEquals("success", response.getString("status")); - final JsonArray responseKeys = response.getJsonArray("body"); - assertNotNull(responseKeys); - assertEquals(expectedKeys.length, responseKeys.size()); - for (int i = 0; i < expectedKeys.length; ++i) { - KeysetKey expectedKey = expectedKeys[i]; - Keyset keyset = keysetProvider.getSnapshot().getKeyset(expectedKey.getKeysetId()); - - JsonObject actualKey = responseKeys.getJsonObject(i); - assertEquals(expectedKey.getId(), actualKey.getInteger("id")); - assertArrayEquals(expectedKey.getKeyBytes(), actualKey.getBinary("secret")); - assertEquals(expectedKey.getCreated().truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(actualKey.getLong("created"))); - assertEquals(expectedKey.getActivates().truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(actualKey.getLong("activates"))); - assertEquals(expectedKey.getExpires().truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(actualKey.getLong("expires"))); - assertEquals(keyset.getSiteId(), actualKey.getInteger("site_id")); + + final JsonArray expected = new JsonArray(); + for (KeysetKey key : expectedKeys) { + final JsonObject expectedKey = new JsonObject(); + expectedKey.put("id", key.getId()); + expectedKey.put("secret", Base64.getEncoder().encodeToString(key.getKeyBytes())); + expectedKey.put("created", key.getCreated().getEpochSecond()); + expectedKey.put("activates", key.getActivates().getEpochSecond()); + expectedKey.put("expires", key.getExpires().getEpochSecond()); + expectedKey.put("site_id", keysetProvider.getSnapshot().getKeyset(key.getKeysetId()).getSiteId()); + expected.add(expectedKey); } + + assertEquals(expected, response.getJsonArray("body")); } private void checkEncryptionKeys(JsonObject response, KeyDownloadEndpoint endpoint, int callersSiteId, KeysetKey... expectedKeys) { assertEquals("success", response.getString("status")); - final JsonArray responseKeys = response.getJsonObject("body").getJsonArray("keys"); - assertNotNull(responseKeys); - assertEquals(expectedKeys.length, responseKeys.size()); - for (int i = 0; i < expectedKeys.length; ++i) { - KeysetKey expectedKey = expectedKeys[i]; - JsonObject actualKey = responseKeys.getJsonObject(i); - assertEquals(expectedKey.getId(), actualKey.getInteger("id")); - assertArrayEquals(expectedKey.getKeyBytes(), actualKey.getBinary("secret")); - assertEquals(expectedKey.getCreated().truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(actualKey.getLong("created"))); - assertEquals(expectedKey.getActivates().truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(actualKey.getLong("activates"))); - assertEquals(expectedKey.getExpires().truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(actualKey.getLong("expires"))); - - Keyset expectedKeyset = this.keysetProvider.getSnapshot().getKeyset(expectedKey.getKeysetId()); + + final JsonArray expected = new JsonArray(); + for (KeysetKey key : expectedKeys) { + final Keyset expectedKeyset = this.keysetProvider.getSnapshot().getKeyset(key.getKeysetId()); assertNotNull(expectedKeyset); assertTrue(expectedKeyset.isEnabled()); - final var actualKeysetId = actualKey.getInteger("keyset_id"); - - switch (endpoint) { - case SHARING: - assertTrue(actualKeysetId == null || actualKeysetId > 0); //SDKs currently have an assumption that keyset ids are positive; that will be fixed. - - if (expectedKeyset.getSiteId() == callersSiteId) { - assertEquals(expectedKey.getKeysetId(), actualKeysetId); - } else if (expectedKeyset.getSiteId() == MasterKeySiteId) { - assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, actualKeysetId); - } else { - assertNull(actualKeysetId); //we only send keyset ids if the caller is allowed to encrypt using that keyset (so only the caller's keysets and the master keyset) - } - break; - case BIDSTREAM: - assertNull(actualKeysetId); - break; + final JsonObject expectedKey = new JsonObject(); + expectedKey.put("id", key.getId()); + expectedKey.put("secret", Base64.getEncoder().encodeToString(key.getKeyBytes())); + expectedKey.put("created", key.getCreated().getEpochSecond()); + expectedKey.put("activates", key.getActivates().getEpochSecond()); + expectedKey.put("expires", key.getExpires().getEpochSecond()); + + if (endpoint == KeyDownloadEndpoint.SHARING) { + // We only send keyset ids if the caller is allowed to encrypt using that keyset (so only the caller's keysets and the master keyset) + if (expectedKeyset.getSiteId() == callersSiteId) { + // SDKs currently have an assumption that keyset ids are positive; that will be fixed. + assertTrue(key.getKeysetId() > 0); + expectedKey.put("keyset_id", key.getKeysetId()); + } else if (expectedKeyset.getSiteId() == MasterKeySiteId) { + expectedKey.put("keyset_id", UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS); + } } + + expected.add(expectedKey); } + + assertEquals(expected, response.getJsonObject("body").getJsonArray("keys")); } private enum KeyDownloadEndpoint { @@ -4358,32 +4351,29 @@ void keyDownloadEndpointRotatingKeysets_IDREADER(String testRun, KeyDownloadEndp } private void checkKeyDownloadResponseHeaderFields(KeyDownloadEndpoint endpoint, JsonObject body, int clientSiteId) { - assertEquals(this.getIdentityScope().toString(), body.getString("identity_scope")); - assertEquals(config.getInteger(Const.Config.AllowClockSkewSecondsProp), body.getInteger("allow_clock_skew_seconds")); + final JsonObject bodyHeaders = body.copy(); + bodyHeaders.remove("site_data"); + bodyHeaders.remove("keys"); + + final JsonObject expected = new JsonObject() + .put("identity_scope", this.getIdentityScope().toString()) + .put("allow_clock_skew_seconds", config.getInteger(Const.Config.AllowClockSkewSecondsProp)); switch (endpoint) { case SHARING: - assertEquals(clientSiteId, body.getInteger("caller_site_id")); - assertEquals(UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS, body.getInteger("master_keyset_id")); - assertEquals(4, body.getInteger("default_keyset_id")); + expected.put("caller_site_id", clientSiteId); + expected.put("master_keyset_id", UIDOperatorVerticle.MASTER_KEYSET_ID_FOR_SDKS); + expected.put("default_keyset_id", 4); // NOTE: this is intentionally a string, not an integer. See comment in UIDOperatorVerticle. - assertEquals(config.getInteger(Const.Config.SharingTokenExpiryProp), Integer.parseInt(body.getString("token_expiry_seconds"))); - - // Check that /key/bidstream fields are not present. - assertFalse(body.containsKey("max_bidstream_lifetime_seconds")); + expected.put("token_expiry_seconds", config.getInteger(Const.Config.SharingTokenExpiryProp).toString()); break; case BIDSTREAM: final int expectedMaxBidstreamLifetimeSeconds = config.getInteger(Const.Config.MaxBidstreamLifetimeSecondsProp, config.getInteger(UIDOperatorService.IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS)); - assertEquals(expectedMaxBidstreamLifetimeSeconds + TOKEN_LIFETIME_TOLERANCE.toSeconds(), body.getLong("max_bidstream_lifetime_seconds")); - - // Check that /key/sharing header fields are not present. - assertFalse(body.containsKey("caller_site_id")); - assertFalse(body.containsKey("default_keyset_id")); - assertFalse(body.containsKey("master_keyset_id")); - assertFalse(body.containsKey("max_sharing_lifetime_seconds")); - assertFalse(body.containsKey("token_expiry_seconds")); + expected.put("max_bidstream_lifetime_seconds", expectedMaxBidstreamLifetimeSeconds + TOKEN_LIFETIME_TOLERANCE.toSeconds()); break; } + + assertEquals(expected, bodyHeaders); } @Test From cddb9eb7410d00490bdf338a6a54fe8922cf3d30 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 13 Mar 2024 02:21:51 +0000 Subject: [PATCH 0238/1116] [CI Pipeline] Released Minor version: 5.28.0-cc0338a89a --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f79d73763..1a5b941c2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.27.44-51b2f952f3 + 5.28.0-cc0338a89a UTF-8 diff --git a/version.json b/version.json index 880381b5c..e93c43b41 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.27", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.28", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From d6df4edebdfc3ccc679f6a26c1e31c456726cd7c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 13 Mar 2024 04:29:59 +0000 Subject: [PATCH 0239/1116] [CI Pipeline] Released Patch version: 5.28.2-afa9598348 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1a5b941c2..90becf8fd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.0-cc0338a89a + 5.28.2-afa9598348 UTF-8 From d522a00f8bfac1cb442692084148eec74204c235 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 13 Mar 2024 13:09:26 +0800 Subject: [PATCH 0240/1116] Removed 2.0 from EUID --- scripts/aws/EUID_CloudFormation.template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/EUID_CloudFormation.template.yml b/scripts/aws/EUID_CloudFormation.template.yml index c435bb251..1eeb2f5c5 100644 --- a/scripts/aws/EUID_CloudFormation.template.yml +++ b/scripts/aws/EUID_CloudFormation.template.yml @@ -1,5 +1,5 @@ AWSTemplateFormatVersion: 2010-09-09 -Description: EUID 2.0 CloudFormation template +Description: EUID CloudFormation template Parameters: APIToken: Description: EUID API Token From 1d656fcb349cac9544b78b058cd61b3374e86eeb Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 13 Mar 2024 16:21:06 +1100 Subject: [PATCH 0241/1116] UID2-2890 Hardcode the /app/conf/logback.xml path (#406) * Hardcode the ./conf/logback.xml path * Use /app/conf/logback.xml --- scripts/azure-cc/Dockerfile | 1 - scripts/azure-cc/entrypoint.sh | 2 +- scripts/gcp-oidc/Dockerfile | 1 - scripts/gcp-oidc/entrypoint.sh | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/azure-cc/Dockerfile b/scripts/azure-cc/Dockerfile index a69e67619..2e713f4ae 100644 --- a/scripts/azure-cc/Dockerfile +++ b/scripts/azure-cc/Dockerfile @@ -14,7 +14,6 @@ ENV JAR_VERSION=${JAR_VERSION} ENV IMAGE_VERSION=${IMAGE_VERSION} ENV REGION=default ENV LOKI_HOSTNAME=loki -ENV LOGBACK_CONF=${LOGBACK_CONF:-./conf/logback.xml} COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar COPY ./target/${JAR_NAME}-${JAR_VERSION}-sources.jar /app diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index 5a2afc4ec..3fd88bbce 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -58,6 +58,6 @@ java \ -XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \ -Djava.security.egd=file:/dev/./urandom \ -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory \ - -Dlogback.configurationFile=${LOGBACK_CONF} \ + -Dlogback.configurationFile=/app/conf/logback.xml \ -Dvertx-config-path=${FINAL_CONFIG} \ -jar ${JAR_NAME}-${JAR_VERSION}.jar diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 907ea7a96..d0ad1f86c 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -16,7 +16,6 @@ ENV JAR_VERSION=${JAR_VERSION} ENV IMAGE_VERSION=${IMAGE_VERSION} ENV REGION=default ENV LOKI_HOSTNAME=loki -ENV LOGBACK_CONF=${LOGBACK_CONF:-./conf/logback.xml} COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar COPY ./target/${JAR_NAME}-${JAR_VERSION}-sources.jar /app diff --git a/scripts/gcp-oidc/entrypoint.sh b/scripts/gcp-oidc/entrypoint.sh index 5731af324..133b54486 100644 --- a/scripts/gcp-oidc/entrypoint.sh +++ b/scripts/gcp-oidc/entrypoint.sh @@ -59,6 +59,6 @@ java \ -XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \ -Djava.security.egd=file:/dev/./urandom \ -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory \ - -Dlogback.configurationFile=${LOGBACK_CONF} \ + -Dlogback.configurationFile=/app/conf/logback.xml \ -Dvertx-config-path=${FINAL_CONFIG} \ -jar ${JAR_NAME}-${JAR_VERSION}.jar From f202313f1eec75425862a3521f7f6e3361736f47 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 13 Mar 2024 13:33:07 +0800 Subject: [PATCH 0242/1116] Removed unneeded bash function --- scripts/aws/entrypoint.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 6575a261c..54b81507c 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -73,17 +73,6 @@ get_config_value() { jq -r ".\"$1\"" ${FINAL_CONFIG} } -# for number/boolean -# https://jqlang.github.io/jq/manual/ -# --argjson foo 123 will bind $foo to 123. -TMP_FINAL_CONFIG="/tmp/final-config.tmp" -function jq_inplace_update_json() { - local file=$1 - local field=$2 - local value=$3 - jq --argjson v "${value}" ".${field} = \$v" "${file}" > "${TMP_FINAL_CONFIG}" && mv "${TMP_FINAL_CONFIG}" "${file}" -} - # -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided # -- using hardcoded domains is fine because they should not be changed frequently if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then From 20ce2767df059a5227c6a323076baf14a53a3989 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 13 Mar 2024 13:42:59 +0800 Subject: [PATCH 0243/1116] Updated E2E test pipeline input params --- .../workflows/run-e2e-tests-on-operator.yaml | 101 ++++++++++-------- 1 file changed, 59 insertions(+), 42 deletions(-) diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 56d616adb..05f7b4eef 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -12,7 +12,6 @@ on: - gcp - azure - aws - identity_scope: description: The identity scope [UID2, EUID] required: true @@ -20,28 +19,34 @@ on: options: - UID2 - EUID - - image_version: - description: The image versions (for gcp/azure, set appropriate operator image) + operator_image_version: + description: 'Image: Operator image version (for gcp/azure, set appropriate image)' type: string - required: true - default: '{ - "operator": "latest", - "core": "latest", - "optout": "latest", - "e2e": "latest" - }' - - branch: - description: The branches for config + default: latest + core_image_version: + description: 'Image: Core image version' type: string - required: true - default: '{ - "core": "main", - "optout": "main", - "admin": "main" - }' - + default: latest + optout_image_version: + description: 'Image: Optout image version' + type: string + default: latest + e2e_image_version: + description: 'Image: E2E image version' + type: string + default: latest + core_branch: + description: 'Config: Core branch for config' + type: string + default: main + optout_branch: + description: 'Config: Optout branch for config' + type: string + default: main + admin_branch: + description: 'Config: Admin branch for config' + type: string + default: main aws: description: The arguments for AWS private operator type: string @@ -61,22 +66,34 @@ on: description: The identity scope [UID2, EUID] type: string default: UID2 - image_version: - description: The image versions (for gcp/azure, set appropriate operator image) + operator_image_version: + description: 'Image: Operator image version (for gcp/azure, set appropriate image)' type: string - default: '{ - "operator": "latest", - "core": "latest", - "optout": "latest" - }' - branch: - description: The branches for config + default: latest + core_image_version: + description: 'Image: Core image version' type: string - default: '{ - "core": "main", - "optout": "main", - "admin": "main" - }' + default: latest + optout_image_version: + description: 'Image: Optout image version' + type: string + default: latest + e2e_image_version: + description: 'Image: E2E image version' + type: string + default: latest + core_branch: + description: 'Config: Core branch for config' + type: string + default: main + optout_branch: + description: 'Config: Optout branch for config' + type: string + default: main + admin_branch: + description: 'Config: Admin branch for config' + type: string + default: main aws: description: The arguments for AWS private operator type: string @@ -92,14 +109,14 @@ jobs: uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-run-e2e-tests.yaml@v2 with: operator_type: ${{ inputs.operator_type }} - operator_image_version: ${{ fromJson(inputs.image_version).operator }} - core_image_version: ${{ fromJson(inputs.image_version).core }} - optout_image_version: ${{ fromJson(inputs.image_version).optout }} - e2e_image_version: ${{ fromJson(inputs.image_version).e2e }} + operator_image_version: ${{ inputs.operator_image_version }} + core_image_version: ${{ inputs.core_image_version }} + optout_image_version: ${{ inputs.optout_image_version }} + e2e_image_version: ${{ inputs.e2e_image_version }} operator_branch: ${{ github.ref }} - core_branch: ${{ fromJson(inputs.branch).core }} - optout_branch: ${{ fromJson(inputs.branch).optout }} - admin_branch: ${{ fromJson(inputs.branch).admin }} + core_branch: ${{ inputs.core_branch }} + optout_branch: ${{ inputs.optout_branch }} + admin_branch: ${{ inputs.admin_branch }} uid2_e2e_identity_scope: ${{ inputs.identity_scope }} gcp_workload_identity_provider_id: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER_ID }} gcp_service_account: ${{ vars.GCP_SERVICE_ACCOUNT }} From 4265d6ceb3446f0b772621efa271d64e61144350 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 13 Mar 2024 14:16:35 +0800 Subject: [PATCH 0244/1116] Removed unneeded operator_branch variable --- .github/workflows/publish-public-operator-docker-image.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 49a829b2b..bb619b64c 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -58,7 +58,6 @@ jobs: needs: image with: operator_image_version: ${{ needs.image.outputs.image_tag }} - operator_branch: ${{ github.ref }} secrets: inherit collectAllArtifacts: From b8e0b32efdfc4eea97f3c05ec1b7480145f13e23 Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 13 Mar 2024 14:21:13 +0800 Subject: [PATCH 0245/1116] Removed further references of operator_branch --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 1 - .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index de9b262bd..a7a2e9f6e 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -255,5 +255,4 @@ jobs: with: operator_type: azure operator_image_version: ${{ needs.buildImage.outputs.image_tag }} - operator_branch: ${{ github.ref }} secrets: inherit diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 67f34354e..a98e89cf0 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -291,5 +291,4 @@ jobs: with: operator_type: gcp operator_image_version: ${{ needs.buildImage.outputs.image_tag }} - operator_branch: ${{ github.ref }} secrets: inherit From e4f53d4b0a81cc1659ba91a701f1a6ba3a237fba Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 13 Mar 2024 07:12:31 +0000 Subject: [PATCH 0246/1116] [CI Pipeline] Released Patch version: 5.28.12-8ebcc578b6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 90becf8fd..44b09d6e5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.2-afa9598348 + 5.28.12-8ebcc578b6 UTF-8 From b7b283489bed2dab7320e8814cda954992a6803a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 14 Mar 2024 05:04:36 +0000 Subject: [PATCH 0247/1116] [CI Pipeline] Released Patch version: 5.28.14-3e9aa4187a --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44b09d6e5..83e62bd8e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.12-8ebcc578b6 + 5.28.14-3e9aa4187a UTF-8 From 2aba9e139b27b3a44d65f8121465864186fe152c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 10:21:32 +1100 Subject: [PATCH 0248/1116] Save the 2 eif files as different artifacts --- .../workflows/publish-aws-nitro-enclave-docker.yaml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index b26bc365e..8ee912526 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -119,19 +119,26 @@ jobs: uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 - artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + - name: Archive deployment artifacts + uses: actions/upload-artifact@v4 + with: + name: aws-nitro-deployment-files + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + if-no-files-found: error + - name: Build EUID AWS EIF uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid - artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - name: Archive deployment artifacts uses: actions/upload-artifact@v4 with: name: aws-nitro-deployment-files - path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }} + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error - name: Generate release archive From b8f4a108e9c5cdd51437362253d479be7ecbf52f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 17 Mar 2024 23:23:34 +0000 Subject: [PATCH 0249/1116] Released Snapshot version: 5.28.17-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 83e62bd8e..6f3adcf0e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.14-3e9aa4187a + 5.28.17-SNAPSHOT UTF-8 From e87ef232d50adc27da9fd7c6bf57476782247292 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 10:39:17 +1100 Subject: [PATCH 0250/1116] Changed the artifact names --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 8ee912526..41c630eee 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -124,7 +124,7 @@ jobs: - name: Archive deployment artifacts uses: actions/upload-artifact@v4 with: - name: aws-nitro-deployment-files + name: uid2-nitro-deployment-files path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error @@ -137,7 +137,7 @@ jobs: - name: Archive deployment artifacts uses: actions/upload-artifact@v4 with: - name: aws-nitro-deployment-files + name: euid-nitro-deployment-files path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error From 419b5a6ec4b43022966b90c8b5ef4dbc9581efc0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 17 Mar 2024 23:40:01 +0000 Subject: [PATCH 0251/1116] Released Snapshot version: 5.28.19-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6f3adcf0e..60490029a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.17-SNAPSHOT + 5.28.19-SNAPSHOT UTF-8 From a874909dee21c996cd6abec579ee03cf6bfa7497 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 11:13:02 +1100 Subject: [PATCH 0252/1116] Only add artifacts if not release --- .../publish-aws-nitro-enclave-docker.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 41c630eee..389c9d351 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -122,9 +122,10 @@ jobs: artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - name: Archive deployment artifacts + if: ${{ inputs.version_number_input != '' || steps.checkRelease.outputs.is_release != 'true' }} uses: actions/upload-artifact@v4 with: - name: uid2-nitro-deployment-files + name: uid2-nitro-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error @@ -135,16 +136,18 @@ jobs: artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - name: Archive deployment artifacts + if: ${{ inputs.version_number_input != '' || steps.checkRelease.outputs.is_release != 'true' }} uses: actions/upload-artifact@v4 with: - name: euid-nitro-deployment-files + name: euid-nitro-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error - - name: Generate release archive + - name: Generate release archive files if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | - zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - name: Build changelog id: github_release @@ -153,7 +156,7 @@ jobs: with: configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.updatePom.outputs.image_tag }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.version.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.updatePom.outputs.image_tag }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: @@ -167,4 +170,6 @@ jobs: body: ${{ steps.github_release.outputs.changelog }} draft: true files: | - ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + From 02c7fd4972f16aedaa37edf54ce21d6288a92bf9 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 18 Mar 2024 00:14:37 +0000 Subject: [PATCH 0253/1116] Released Snapshot version: 5.28.21-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 60490029a..e305ff231 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.19-SNAPSHOT + 5.28.21-SNAPSHOT UTF-8 From 2cc3d2554c700983e8617982bb5363bc8e00a85c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 11:36:03 +1100 Subject: [PATCH 0254/1116] Revert pom.xml version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 60490029a..83e62bd8e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.19-SNAPSHOT + 5.28.14-3e9aa4187a UTF-8 From 9110b07f1e51b08c72ed8b761148aa72487700d9 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 12:51:30 +1100 Subject: [PATCH 0255/1116] Change to use shared action for commit --- .../publish-aws-nitro-enclave-docker.yaml | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 389c9d351..44a66561e 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -59,7 +59,7 @@ jobs: shell: bash env: GITHUB_CONTEXT: ${{ toJson(github) }} - IS_RELEASE: ${{ steps.checkRelease.outputs.IS_RELEASE }} + IS_RELEASE: ${{ steps.checkRelease.outputs.is_release }} - name: Checkout full history on Main uses: actions/checkout@v4 @@ -77,7 +77,7 @@ jobs: fetch-depth: 0 - name: Restore timestamps - uses: thetradedesk/git-restore-mtime-action@v1.2 + uses: thetradedesk/git-restore-mtime-action@v1.3 - name: Set version number id: version @@ -97,23 +97,19 @@ jobs: echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT - name: Commit pom.xml and version.json - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE != 'true' }} - uses: EndBug/add-and-commit@v9 + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release != 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - name: Commit pom.xml, version.json and set tag - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.IS_RELEASE == 'true' }} - uses: EndBug/add-and-commit@v9 + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 with: add: 'pom.xml version.json' - author_name: Release Workflow - author_email: unifiedid-admin+release@thetradedesk.com message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} + tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main @@ -156,7 +152,7 @@ jobs: with: configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.version.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.updatePom.outputs.image_tag }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "#{{CHANGELOG}}\n## Installation\n```\See [AWS Marketplace](https://unifiedid.com/docs/guides/operator-guide-aws-marketplace) for details\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: From 779889b3adf8bf60946d0b4ce6eed7eb279ee364 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 18 Mar 2024 01:55:20 +0000 Subject: [PATCH 0256/1116] [CI Pipeline] Released Patch version: 5.28.26-6742ca7a3b --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 83e62bd8e..30a639b9a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.14-3e9aa4187a + 5.28.26-6742ca7a3b UTF-8 From 1a78e989f30ee39e307962a2cc6723d8d0b31ea6 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 13:19:49 +1100 Subject: [PATCH 0257/1116] Updated paths --- .github/actions/build_aws_eif/action.yaml | 2 +- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 0a075730d..332f4b6db 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -47,7 +47,7 @@ runs: - name: Prepare artifacts shell: bash run: | - ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}/${{ inputs.identity_scope }}" + ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}" mkdir -p ${ARTIFACTS_OUTPUT_DIR} diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 44a66561e..178f5d338 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -142,6 +142,8 @@ jobs: - name: Generate release archive files if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | + ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* From 46cc9c51469d60f4a098e86f24d8f97c8869aa6f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 18 Mar 2024 02:24:17 +0000 Subject: [PATCH 0258/1116] [CI Pipeline] Released Patch version: 5.28.30-fd0e5381bb --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 30a639b9a..5c4797d2b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.26-6742ca7a3b + 5.28.30-fd0e5381bb UTF-8 From 44d6c72644bd879130304f09f5892b8aa25e5d9f Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 18 Mar 2024 13:42:18 +1100 Subject: [PATCH 0259/1116] Save the eif as a build artifact regardless of release --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 178f5d338..c619771bb 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -117,8 +117,7 @@ jobs: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - - name: Archive deployment artifacts - if: ${{ inputs.version_number_input != '' || steps.checkRelease.outputs.is_release != 'true' }} + - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: name: uid2-nitro-deployment-files-${{ steps.version.outputs.new_version }} @@ -131,8 +130,7 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - - name: Archive deployment artifacts - if: ${{ inputs.version_number_input != '' || steps.checkRelease.outputs.is_release != 'true' }} + - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: name: euid-nitro-deployment-files-${{ steps.version.outputs.new_version }} From caf8404f522ba7be4b07c40fa2e488f25634e03e Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 18 Mar 2024 03:48:01 +0000 Subject: [PATCH 0260/1116] [CI Pipeline] Released Patch version: 5.28.34-cbc25262b8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c4797d2b..1041ed096 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.30-fd0e5381bb + 5.28.34-cbc25262b8 UTF-8 From b2571b8764ff6fc2500e07a8c5b71d543d9b4cd8 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 10:27:29 +1100 Subject: [PATCH 0261/1116] Returning enclave id as artifact --- .github/actions/build_aws_eif/action.yaml | 9 +++++++++ .github/workflows/publish-all-operators.yaml | 4 ++-- .../publish-aws-nitro-enclave-docker.yaml | 14 +++++++++++--- .../workflows/publish-azure-cc-enclave-docker.yaml | 6 +++--- .../workflows/publish-gcp-oidc-enclave-docker.yaml | 2 +- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 332f4b6db..7f3a0d4c0 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -9,6 +9,11 @@ inputs: description: The base output directory for the AMI artifacts required: true +outputs: + enclave_id: + description: The enclave id for this EIF. + value: ${{ steps.prepare_artifacts.outputs.enclave_id }} + runs: using: "composite" @@ -45,6 +50,7 @@ runs: make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif - name: Prepare artifacts + id: prepare_artifacts shell: bash run: | ARTIFACTS_OUTPUT_DIR="${{ inputs.artifacts_base_output_dir }}" @@ -63,7 +69,10 @@ runs: docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/${{ inputs.identity_scope }}operator.eif ${ARTIFACTS_OUTPUT_DIR}/uid2operator.eif + + docker cp amazonlinux:/pcr0.txt ${{ steps.buildFolder.outputs.BUILD_FOLDER }} docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ + echo "enclave_id=$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER}}/pcr0.txt)" >> $GITHUB_OUTPUT - name: Cleanup shell: bash diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 627753478..2e66836df 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -153,7 +153,7 @@ jobs: release: name: Create Release runs-on: ubuntu-latest - needs: [start, collectAllArtifacts] + needs: [start, buildPublic, buildGCP, buildAzure, buildAWS] steps: - name: Extract metadata (tags, labels) for Docker id: meta @@ -177,7 +177,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create draft release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: name: ${{ needs.start.outputs.new_version }} body: ${{ steps.changelog.outputs.changelog }} diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index c619771bb..ea0b1685f 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -112,7 +112,8 @@ jobs: tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + id: build_uid2_eif + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2982-update-output-manifests with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -125,7 +126,8 @@ jobs: if-no-files-found: error - name: Build EUID AWS EIF - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + id: build_euid_eif + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2982-update-output-manifests with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid @@ -144,6 +146,10 @@ jobs: ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/uid2-enclave-id.txt + echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/uid2-enclave-id.txt + touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/euid-enclave-id.txt + echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/euid-enclave-id.txt - name: Build changelog id: github_release @@ -160,7 +166,7 @@ jobs: - name: Create release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: name: ${{ steps.version.outputs.new_version }} body: ${{ steps.github_release.outputs.changelog }} @@ -168,4 +174,6 @@ jobs: files: | ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/uid2-enclave-id.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/euid-enclave-id.txt diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index a7a2e9f6e..38bb3ca54 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -85,14 +85,14 @@ jobs: - name: Checkout full history on Main uses: actions/checkout@v4 - if: ${{ inputs.version_number_input == ''}} + if: ${{ inputs.version_number_input == '' }} with: # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. fetch-depth: 0 - name: Checkout full history at tag v${{ inputs.version_number_input }} uses: actions/checkout@v4 - if: ${{ inputs.version_number_input != ''}} + if: ${{ inputs.version_number_input != '' }} with: ref: v${{ inputs.version_number_input }} # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. @@ -240,7 +240,7 @@ jobs: - name: Create release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: name: ${{ steps.version.outputs.new_version }} body: ${{ steps.github_release.outputs.changelog }} diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index a98e89cf0..2c1c51250 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -276,7 +276,7 @@ jobs: - name: Create release if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: name: ${{ steps.version.outputs.new_version }} body: ${{ steps.github_release.outputs.changelog }} From c50aaa7b78e211bea321d610deb05ed4aa6be021 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 18 Mar 2024 23:28:36 +0000 Subject: [PATCH 0262/1116] [CI Pipeline] Released Snapshot version: 5.28.37-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1041ed096..cc4d025ff 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.34-cbc25262b8 + 5.28.37-SNAPSHOT UTF-8 From fa88898fb6d0fc9988ca17a7b52c3e81eaba1629 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 11:06:00 +1100 Subject: [PATCH 0263/1116] Update the generation of enclave ids --- .../publish-aws-nitro-enclave-docker.yaml | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ea0b1685f..ea024c00a 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -26,11 +26,6 @@ on: type: string default: '' - outputs: - pcr0: - description: The EIF PCR0 - value: ${{ jobs.buildImage.outputs.pcr0 }} - env: ENCLAVE_PROTOCOL: aws-nitro ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts @@ -39,8 +34,6 @@ jobs: buildImage: name: Build Image runs-on: ubuntu-latest - outputs: - pcr0: ${{ steps.showPCR0.outputs.PCR0 }} steps: - name: Check branch and release type id: checkRelease @@ -139,6 +132,21 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error + - name: Save Enclave Ids + run: | + mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests + touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt + echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt + touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt + echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt + + - name: Save Manifests as build artifacts + uses: actions/upload-artifact@v4 + with: + name: aws-enclave-ids-${{ steps.version.outputs.new_version }} + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests + if-no-files-found: error + - name: Generate release archive files if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | @@ -146,10 +154,6 @@ jobs: ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/uid2-enclave-id.txt - echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/uid2-enclave-id.txt - touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/euid-enclave-id.txt - echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/euid-enclave-id.txt - name: Build changelog id: github_release @@ -174,6 +178,6 @@ jobs: files: | ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/uid2-enclave-id.txt - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/euid-enclave-id.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt From 0873d6ac53ebf2bfa8a33fab6679b0dba1a30e43 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 00:06:52 +0000 Subject: [PATCH 0264/1116] [CI Pipeline] Released Snapshot version: 5.28.39-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cc4d025ff..5eb6e991c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.37-SNAPSHOT + 5.28.39-SNAPSHOT UTF-8 From 9dab9849cb0c839774b2b1667b98da715bf92d8e Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 11:11:49 +1100 Subject: [PATCH 0265/1116] Update Azure to save manifest --- .../workflows/publish-azure-cc-enclave-docker.yaml | 12 +++++++++++- .../deployment/generate-deployment-artifacts.sh | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 38bb3ca54..75da854a2 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -47,6 +47,7 @@ env: IMAGE_NAME: ${{ github.repository }} DOCKER_CONTEXT_PATH: scripts/azure-cc ARTIFACTS_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts + MANIFEST_OUTPUT_DIR: ${{ github.workspace }}/manifest jobs: buildImage: @@ -210,16 +211,24 @@ jobs: env: IMAGE: ${{ steps.meta.outputs.tags }} OUTPUT_DIR: ${{ env.ARTIFACTS_OUTPUT_DIR }} + MANIFEST_DIR: ${{ env.MANIFEST_OUTPUT_DIR }} run: | bash ./scripts/azure-cc/deployment/generate-deployment-artifacts.sh - - name: Archive deployment artifacts + - name: Upload deployment artifacts uses: actions/upload-artifact@v4 with: name: azure-cc-deployment-files path: ${{ env.ARTIFACTS_OUTPUT_DIR }} if-no-files-found: error + - name: Upload manifest + uses: actions/upload-artifact@v4 + with: + name: azure-cc-enclave-id + path: ${{ env.MANIFEST_OUTPUT_DIR }} + if-no-files-found: error + - name: Generate release archive if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | @@ -247,6 +256,7 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip + ${{ env.MANIFEST_OUTPUT_DIR }}/azure-cc-operator-digest.txt e2e: name: E2E diff --git a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh index 97c4c5a47..6f64860a3 100644 --- a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh +++ b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh @@ -4,6 +4,7 @@ set -x # Following environment variables must be set # - IMAGE: uid2-operator image # - OUTPUT_DIR: output directory to store the artifacts +# - MANIFEST_DIR: output directory to store the manifest for the enclave Id SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) INPUT_DIR=${SCRIPT_DIR} @@ -68,8 +69,8 @@ if [[ $? -ne 0 ]]; then exit 1 fi -POLICY_DIGEST_FILE=operator-digest.txt -az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json > ${OUTPUT_DIR}/${POLICY_DIGEST_FILE} +POLICY_DIGEST_FILE=azure-cc-operator-digest.txt +az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json > ${MANIFEST_DIR}/${POLICY_DIGEST_FILE} if [[ $? -ne 0 ]]; then echo "Failed to generate operator template file" exit 1 From 6dc1fb50f882761f4a2e4786cec2ab12fb88f617 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 00:15:42 +0000 Subject: [PATCH 0266/1116] [CI Pipeline] Released Snapshot version: 5.28.41-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5eb6e991c..8fa260a74 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.39-SNAPSHOT + 5.28.41-SNAPSHOT UTF-8 From 6b1c71adf34bab673b00467a82c38561b81a57d5 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 11:21:30 +1100 Subject: [PATCH 0267/1116] Update GCP to save enclave id --- .../workflows/publish-gcp-oidc-enclave-docker.yaml | 13 ++++++++++++- scripts/gcp-oidc/generate-deployment-artifacts.sh | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 2c1c51250..d463df8ca 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -48,6 +48,7 @@ env: IMAGE_NAME: ${{ github.repository }} DOCKER_CONTEXT_PATH: scripts/gcp-oidc ARTIFACTS_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts + MANIFEST_OUTPUT_DIR: ${{ github.workspace }}/manifests jobs: buildImage: @@ -246,16 +247,24 @@ jobs: IMAGE: ${{ steps.meta-gcp.outputs.tags }} IMAGE_DIGEST: ${{ steps.push-to-docker.outputs.digest }} OUTPUT_DIR: ${{ env.ARTIFACTS_OUTPUT_DIR }} + MANIFEST_DIR: ${{ env.MANIFEST_OUTPUT_DIR}} run: | bash ./scripts/gcp-oidc/generate-deployment-artifacts.sh - - name: Archive deployment artifacts + - name: Upload deployment artifacts uses: actions/upload-artifact@v4 with: name: gcp-oidc-deployment-files path: ${{ env.ARTIFACTS_OUTPUT_DIR }} if-no-files-found: error + - name: Upload manifest artifacts + uses: actions/upload-artifact@v4 + with: + name: gcp-oidc-enclave-ids + path: ${{ env.MANIFEST_OUTPUT_DIR }} + if-no-files-found: error + - name: Generate release archive if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | @@ -283,6 +292,8 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip + ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id.txt + ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id_debug.txt e2e: name: E2E diff --git a/scripts/gcp-oidc/generate-deployment-artifacts.sh b/scripts/gcp-oidc/generate-deployment-artifacts.sh index 6842a37b2..32001317b 100644 --- a/scripts/gcp-oidc/generate-deployment-artifacts.sh +++ b/scripts/gcp-oidc/generate-deployment-artifacts.sh @@ -5,6 +5,7 @@ set -x # - IMAGE: uid2-operator image # - IMAGE_DIGEST: uid2-operator image digest # - OUTPUT_DIR: output directory to store the artifacts +# - MANIFEST_DIR: output directory to store the manifest for the enclave Id SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) INPUT_DIR=${SCRIPT_DIR}/terraform @@ -52,14 +53,14 @@ if [[ $? -ne 0 ]]; then fi # Enclave ID file -echo -n "V1,false,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${OUTPUT_DIR}/enclave_id.txt +echo -n "V1,false,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id.txt if [[ $? -ne 0 ]]; then echo "Failed to generate non-debug enclave ID file" exit 1 fi # Enclave ID file for debug -echo -n "V1,true,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${OUTPUT_DIR}/enclave_id_debug.txt +echo -n "V1,true,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id_debug.txt if [[ $? -ne 0 ]]; then echo "Failed to generate debug enclave ID file" exit 1 From 575afcf5e2d711eba392e6192fc57abf2028127c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 11:26:32 +1100 Subject: [PATCH 0268/1116] Create the manifest folder --- .../azure-cc/deployment/generate-deployment-artifacts.sh | 6 ++++++ scripts/gcp-oidc/generate-deployment-artifacts.sh | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh index 6f64860a3..94fbdcc9f 100644 --- a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh +++ b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh @@ -30,6 +30,12 @@ if [[ $? -ne 0 ]]; then exit 1 fi +mkdir -p ${MANIFEST_DIR} +if [[ $? -ne 0 ]]; then + echo "Failed to create ${MANIFEST_DIR}" + exit 1 +fi + # Input files INPUT_FILES=( operator.json operator.parameters.json diff --git a/scripts/gcp-oidc/generate-deployment-artifacts.sh b/scripts/gcp-oidc/generate-deployment-artifacts.sh index 32001317b..eeeb584fe 100644 --- a/scripts/gcp-oidc/generate-deployment-artifacts.sh +++ b/scripts/gcp-oidc/generate-deployment-artifacts.sh @@ -31,6 +31,12 @@ if [[ $? -ne 0 ]]; then exit 1 fi +mkdir -p ${MANIFEST_DIR} +if [[ $? -ne 0 ]]; then + echo "Failed to create ${MANIFEST_DIR}" + exit 1 +fi + # Input files INPUT_FILES=( main.tf outputs.tf variables.tf terraform.tfvars From 7527109b6c08e8b8e7279d832422b73371372c59 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 00:26:41 +0000 Subject: [PATCH 0269/1116] [CI Pipeline] Released Snapshot version: 5.28.43-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8fa260a74..f0563df2d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.41-SNAPSHOT + 5.28.43-SNAPSHOT UTF-8 From 14cb06b24243fabee27bc07efbdbe17b5964efc0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 00:30:08 +0000 Subject: [PATCH 0270/1116] [CI Pipeline] Released Snapshot version: 5.28.45-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f0563df2d..362d9e6e4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.43-SNAPSHOT + 5.28.45-SNAPSHOT UTF-8 From 7c9e43562da98e6c09a990560f5339d68ea12b46 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 11:43:59 +1100 Subject: [PATCH 0271/1116] Update to azure login v2 --- .github/workflows/e2e-azure-cc-enclave.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-azure-cc-enclave.yaml b/.github/workflows/e2e-azure-cc-enclave.yaml index 02fb8734c..084462e1b 100644 --- a/.github/workflows/e2e-azure-cc-enclave.yaml +++ b/.github/workflows/e2e-azure-cc-enclave.yaml @@ -90,7 +90,7 @@ jobs: cd ./e2e && bash ./start_docker.sh - name: Azure Login - uses: azure/login@v1 + uses: azure/login@v2 with: creds: ${{ secrets.AZURE_CREDENTIALS }} From 75148786588b2f2b0e79e4f25e1c42ce69390566 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 13:43:58 +1100 Subject: [PATCH 0272/1116] Adding version number as part of the artifact names --- .github/workflows/publish-all-operators.yaml | 37 +++++++------------ .../publish-aws-nitro-enclave-docker.yaml | 8 ++-- .../publish-azure-cc-enclave-docker.yaml | 3 +- .../publish-gcp-oidc-enclave-docker.yaml | 9 +++-- .../publish-public-operator-docker-image.yaml | 4 +- .../generate-deployment-artifacts.sh | 3 +- .../gcp-oidc/generate-deployment-artifacts.sh | 5 ++- 7 files changed, 32 insertions(+), 37 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 2e66836df..07f9bffca 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -111,44 +111,35 @@ jobs: runs-on: ubuntu-latest needs: [start, buildPublic, buildGCP, buildAzure, buildAWS] steps: - - name: Download public artifacts + - name: Download public manifest uses: actions/download-artifact@v4 with: - name: image-details - path: ./artifacts/public_operator + pattern: image-* + path: ./manifests/public_operator - - name: Download GCP artifacts + - name: Download GCP manifest uses: actions/download-artifact@v4 with: - name: gcp-oidc-deployment-files - path: ./artifacts/gcp_oidc_operator + pattern: enclave_id* + path: ./manifests/gcp_oidc_operator - - name: Download Azure artifacts + - name: Download Azure manifest uses: actions/download-artifact@v4 with: - name: azure-cc-deployment-files - path: ./artifacts/azure_cc_operator + pattern: azure-cc-operator-digest* + path: ./manifests/azure_cc_operator - - name: Download AWS artifacts + - name: Download AWS manifest uses: actions/download-artifact@v4 with: - name: aws-nitro-deployment-files - path: ./artifacts/aws_nitro_operator - - - name: Delete staging artifacts - uses: geekyeggo/delete-artifact@v4 - with: - name: | - image-details - gcp-oidc-deployment-files - azure-cc-deployment-files - aws-nitro-deployment-files + pattern: '*-enclave-id*' + path: ./manifests/aws_nitro_operator - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: uid2-operator-release-${{ needs.start.outputs.new_version }} - path: ./artifacts/ + name: uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests + path: ./manifests/ release: name: Create Release diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ea024c00a..41a5450f1 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -136,9 +136,9 @@ jobs: run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt - echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt + echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt - echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt + echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id-${{ steps.version.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 @@ -178,6 +178,6 @@ jobs: files: | ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id-${{ steps.version.outputs.new_version }}.txt diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 75da854a2..bb7614cca 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -212,6 +212,7 @@ jobs: IMAGE: ${{ steps.meta.outputs.tags }} OUTPUT_DIR: ${{ env.ARTIFACTS_OUTPUT_DIR }} MANIFEST_DIR: ${{ env.MANIFEST_OUTPUT_DIR }} + VERSION_NUMBER: ${{ steps.version.outputs.new_version }} run: | bash ./scripts/azure-cc/deployment/generate-deployment-artifacts.sh @@ -256,7 +257,7 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip - ${{ env.MANIFEST_OUTPUT_DIR }}/azure-cc-operator-digest.txt + ${{ env.MANIFEST_OUTPUT_DIR }}/azure-cc-operator-digest-${{ steps.meta.outputs.version }}.txt e2e: name: E2E diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index d463df8ca..d12011b10 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -248,20 +248,21 @@ jobs: IMAGE_DIGEST: ${{ steps.push-to-docker.outputs.digest }} OUTPUT_DIR: ${{ env.ARTIFACTS_OUTPUT_DIR }} MANIFEST_DIR: ${{ env.MANIFEST_OUTPUT_DIR}} + VERSION_NUMBER: ${{ steps.version.outputs.new_version }} run: | bash ./scripts/gcp-oidc/generate-deployment-artifacts.sh - name: Upload deployment artifacts uses: actions/upload-artifact@v4 with: - name: gcp-oidc-deployment-files + name: gcp-oidc-deployment-files-${{ steps.meta.outputs.version }} path: ${{ env.ARTIFACTS_OUTPUT_DIR }} if-no-files-found: error - name: Upload manifest artifacts uses: actions/upload-artifact@v4 with: - name: gcp-oidc-enclave-ids + name: gcp-oidc-enclave-ids-${{ steps.meta.outputs.version }} path: ${{ env.MANIFEST_OUTPUT_DIR }} if-no-files-found: error @@ -292,8 +293,8 @@ jobs: draft: true files: | ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip - ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id.txt - ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id_debug.txt + ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id_${{ steps.meta.outputs.version }}.txt + ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id_debug_${{ steps.meta.outputs.version }}.txt e2e: name: E2E diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index bb619b64c..de9f5a06a 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -70,10 +70,10 @@ jobs: mkdir -p image-details IMAGE_TAG=${{ needs.image.outputs.image_tag }} IMAGE=$(jq -n --arg img "$IMAGE_TAG" '{image_tag: $img}') - echo $IMAGE > image-details/image.json + echo $IMAGE > image-details/image_$IMAGE_TAG.json - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: image-details + name: image_${{ needs.image.outputs.image_tag }} path: image-details/ diff --git a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh index 94fbdcc9f..375511366 100644 --- a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh +++ b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh @@ -5,6 +5,7 @@ set -x # - IMAGE: uid2-operator image # - OUTPUT_DIR: output directory to store the artifacts # - MANIFEST_DIR: output directory to store the manifest for the enclave Id +# - VERSION_NUMBER: the version number of the build SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) INPUT_DIR=${SCRIPT_DIR} @@ -75,7 +76,7 @@ if [[ $? -ne 0 ]]; then exit 1 fi -POLICY_DIGEST_FILE=azure-cc-operator-digest.txt +POLICY_DIGEST_FILE=azure-cc-operator-digest-$VERSION_NUMBER.txt az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json > ${MANIFEST_DIR}/${POLICY_DIGEST_FILE} if [[ $? -ne 0 ]]; then echo "Failed to generate operator template file" diff --git a/scripts/gcp-oidc/generate-deployment-artifacts.sh b/scripts/gcp-oidc/generate-deployment-artifacts.sh index eeeb584fe..d41e1d9c2 100644 --- a/scripts/gcp-oidc/generate-deployment-artifacts.sh +++ b/scripts/gcp-oidc/generate-deployment-artifacts.sh @@ -6,6 +6,7 @@ set -x # - IMAGE_DIGEST: uid2-operator image digest # - OUTPUT_DIR: output directory to store the artifacts # - MANIFEST_DIR: output directory to store the manifest for the enclave Id +# - VERSION_NUMBER: the version number of the build SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) INPUT_DIR=${SCRIPT_DIR}/terraform @@ -59,14 +60,14 @@ if [[ $? -ne 0 ]]; then fi # Enclave ID file -echo -n "V1,false,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id.txt +echo -n "V1,false,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id_$VERSION_NUMBER.txt if [[ $? -ne 0 ]]; then echo "Failed to generate non-debug enclave ID file" exit 1 fi # Enclave ID file for debug -echo -n "V1,true,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id_debug.txt +echo -n "V1,true,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id_debug_$VERSION_NUMBER.txt if [[ $? -ne 0 ]]; then echo "Failed to generate debug enclave ID file" exit 1 From ea5fbe70af5465d07015ac69c82e86df3b5b43e0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 02:50:32 +0000 Subject: [PATCH 0273/1116] [CI Pipeline] Released Snapshot version: 5.28.48-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 362d9e6e4..952801ed0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.45-SNAPSHOT + 5.28.48-SNAPSHOT UTF-8 From b76605d4ba55a0e3426d66e9466cf3be72b31228 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 02:54:02 +0000 Subject: [PATCH 0274/1116] [CI Pipeline] Released Snapshot version: 5.28.49-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 952801ed0..a7d6c9a17 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.48-SNAPSHOT + 5.28.49-SNAPSHOT UTF-8 From bcafdb0514918883708e249739b26b7bd0455a21 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 14:10:50 +1100 Subject: [PATCH 0275/1116] Updated file names --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 41a5450f1..318bccc6e 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -135,9 +135,7 @@ jobs: - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id.txt echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - touch ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id.txt echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id-${{ steps.version.outputs.new_version }}.txt - name: Save Manifests as build artifacts From 6abffdf640bc583e9ec9698375170b196c4de532 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 19 Mar 2024 14:19:27 +1100 Subject: [PATCH 0276/1116] Revert actions to main branch --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 318bccc6e..ab27f4441 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -106,7 +106,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2982-update-output-manifests + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -120,7 +120,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2982-update-output-manifests + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 75ee777b9fa9817400a0c1760356ce87e1822ebe Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 19 Mar 2024 04:16:46 +0000 Subject: [PATCH 0277/1116] [CI Pipeline] Released Patch version: 5.28.53-c41be09b52 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a7d6c9a17..27d1081f3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.49-SNAPSHOT + 5.28.53-c41be09b52 UTF-8 From fafd018f8d0ddb16912db97ad89a66265d885f4c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 11:03:14 +1100 Subject: [PATCH 0278/1116] Updating the file names --- .github/workflows/publish-all-operators.yaml | 18 ++++---------- .../publish-aws-nitro-enclave-docker.yaml | 24 +++++++++---------- .../publish-azure-cc-enclave-docker.yaml | 8 +++---- .../publish-gcp-oidc-enclave-docker.yaml | 12 +++++----- .../publish-public-operator-docker-image.yaml | 4 ++-- .../gcp-oidc/generate-deployment-artifacts.sh | 4 ++-- 6 files changed, 30 insertions(+), 40 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 07f9bffca..79a09657a 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -114,7 +114,7 @@ jobs: - name: Download public manifest uses: actions/download-artifact@v4 with: - pattern: image-* + pattern: public-image-* path: ./manifests/public_operator - name: Download GCP manifest @@ -132,28 +132,20 @@ jobs: - name: Download AWS manifest uses: actions/download-artifact@v4 with: - pattern: '*-enclave-id*' + pattern: 'aws-enclave-id*' path: ./manifests/aws_nitro_operator - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests - path: ./manifests/ + path: ./manifests release: name: Create Release runs-on: ubuntu-latest - needs: [start, buildPublic, buildGCP, buildAzure, buildAWS] + needs: [start, collectAllArtifacts] steps: - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=raw,value=${{ needs.start.outputs.new_version }}- - - name: Build changelog id: changelog uses: mikepenz/release-changelog-builder-action@v4 @@ -161,7 +153,7 @@ jobs: toTag: v${{ needs.start.outputs.new_version }} configurationJson: | { - "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.meta.outputs.tags }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "template": "\n## Integration Guides\n[AWS Marketplace](https://unifiedid.com/docs/guides/operator-guide-aws-marketplace)\n[GCP Confidential Space](https://unifiedid.com/docs/guides/operator-private-gcp-confidential-space)\n[Microsoft Azure](https://unifiedid.com/docs/guides/operator-guide-azure-enclave)\n\n## Installation\n```\ndocker pull us-docker.pkg.dev/uid2-prod-project/iabtechlab/uid2-operator:${{ needs.start.outputs.new_version }}-gcp-oidc\ndocker pull ghcr.io/iabtechlab/uid2-operator:${{ needs.start.outputs.new_version }}-azure-cc\n```\n## Changelog\n#{{CHANGELOG}}\n#{{UNCATEGORIZED}}", "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" } env: diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ab27f4441..75fdf8061 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -79,7 +79,7 @@ jobs: type: ${{ inputs.release_type }} version_number: ${{ inputs.version_number_input }} branch_name: ${{ github.ref }} - + - name: Update pom.xml id: updatePom run: | @@ -114,7 +114,7 @@ jobs: - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: - name: uid2-nitro-deployment-files-${{ steps.version.outputs.new_version }} + name: aws-uid2-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error @@ -128,15 +128,15 @@ jobs: - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: - name: euid-nitro-deployment-files-${{ steps.version.outputs.new_version }} + name: aws-euid-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id-${{ steps.version.outputs.new_version }}.txt + echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt + echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 @@ -148,10 +148,8 @@ jobs: - name: Generate release archive files if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | - ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - name: Build changelog id: github_release @@ -174,8 +172,8 @@ jobs: body: ${{ steps.github_release.outputs.changelog }} draft: true files: | - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid-nitro-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/euid-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index bb7614cca..06a093001 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -219,14 +219,14 @@ jobs: - name: Upload deployment artifacts uses: actions/upload-artifact@v4 with: - name: azure-cc-deployment-files + name: azure-cc-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_OUTPUT_DIR }} if-no-files-found: error - name: Upload manifest uses: actions/upload-artifact@v4 with: - name: azure-cc-enclave-id + name: azure-cc-enclave-id-${{ steps.version.outputs.new_version }} path: ${{ env.MANIFEST_OUTPUT_DIR }} if-no-files-found: error @@ -256,8 +256,8 @@ jobs: body: ${{ steps.github_release.outputs.changelog }} draft: true files: | - ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip - ${{ env.MANIFEST_OUTPUT_DIR }}/azure-cc-operator-digest-${{ steps.meta.outputs.version }}.txt + ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.MANIFEST_OUTPUT_DIR }}/azure-cc-operator-digest-${{ steps.version.outputs.new_version }}.txt e2e: name: E2E diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index d12011b10..8bd7980b3 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -255,21 +255,21 @@ jobs: - name: Upload deployment artifacts uses: actions/upload-artifact@v4 with: - name: gcp-oidc-deployment-files-${{ steps.meta.outputs.version }} + name: gcp-oidc-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_OUTPUT_DIR }} if-no-files-found: error - name: Upload manifest artifacts uses: actions/upload-artifact@v4 with: - name: gcp-oidc-enclave-ids-${{ steps.meta.outputs.version }} + name: gcp-oidc-enclave-ids-${{ steps.version.outputs.new_version }} path: ${{ env.MANIFEST_OUTPUT_DIR }} if-no-files-found: error - name: Generate release archive if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | - zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* + zip -j ${{ env.ARTIFACTS_OUTPUT_DIR }}/gcp-oidc-deployment-files-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_OUTPUT_DIR }}/* - name: Build changelog id: github_release @@ -292,9 +292,9 @@ jobs: body: ${{ steps.github_release.outputs.changelog }} draft: true files: | - ${{ env.ARTIFACTS_OUTPUT_DIR }}/uid2-operator-deployment-artifacts-${{ steps.meta.outputs.version }}.zip - ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id_${{ steps.meta.outputs.version }}.txt - ${{ env.MANIFEST_OUTPUT_DIR }}/enclave_id_debug_${{ steps.meta.outputs.version }}.txt + ${{ env.ARTIFACTS_OUTPUT_DIR }}/gcp-oidc-deployment-files-${{ steps.version.outputs.new_version }}.zip + ${{ env.MANIFEST_OUTPUT_DIR }}/gcp-oidc-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.MANIFEST_OUTPUT_DIR }}/gcp-oidc-enclave-id-debug-${{ steps.version.outputs.new_version }}.txt e2e: name: E2E diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index de9f5a06a..5258d3570 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -70,10 +70,10 @@ jobs: mkdir -p image-details IMAGE_TAG=${{ needs.image.outputs.image_tag }} IMAGE=$(jq -n --arg img "$IMAGE_TAG" '{image_tag: $img}') - echo $IMAGE > image-details/image_$IMAGE_TAG.json + echo $IMAGE > image-details/public-image-$IMAGE_TAG.json - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: image_${{ needs.image.outputs.image_tag }} + name: public-image-${{ needs.image.outputs.image_tag }} path: image-details/ diff --git a/scripts/gcp-oidc/generate-deployment-artifacts.sh b/scripts/gcp-oidc/generate-deployment-artifacts.sh index d41e1d9c2..eb3b21345 100644 --- a/scripts/gcp-oidc/generate-deployment-artifacts.sh +++ b/scripts/gcp-oidc/generate-deployment-artifacts.sh @@ -60,14 +60,14 @@ if [[ $? -ne 0 ]]; then fi # Enclave ID file -echo -n "V1,false,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id_$VERSION_NUMBER.txt +echo -n "V1,false,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/gcp-oidc-enclave-id-$VERSION_NUMBER.txt if [[ $? -ne 0 ]]; then echo "Failed to generate non-debug enclave ID file" exit 1 fi # Enclave ID file for debug -echo -n "V1,true,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/enclave_id_debug_$VERSION_NUMBER.txt +echo -n "V1,true,$IMAGE_DIGEST" | openssl dgst -sha256 -binary | openssl base64 > ${MANIFEST_DIR}/gcp-oidc-enclave-id-debug-$VERSION_NUMBER.txt if [[ $? -ne 0 ]]; then echo "Failed to generate debug enclave ID file" exit 1 From ad107e21416a34792bc24f0eb27b9c14fb8d9bc0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 20 Mar 2024 00:04:46 +0000 Subject: [PATCH 0279/1116] [CI Pipeline] Released Snapshot version: 5.28.56-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27d1081f3..7eaf356d3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.53-c41be09b52 + 5.28.56-SNAPSHOT UTF-8 From 74f790cbc1793694485c951141c10fc56af24c88 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 20 Mar 2024 00:07:51 +0000 Subject: [PATCH 0280/1116] [CI Pipeline] Released Snapshot version: 5.28.57-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7eaf356d3..5899bb871 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.56-SNAPSHOT + 5.28.57-SNAPSHOT UTF-8 From 39147466686ebbf59cf152684f30bd5507e0a36d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 11:54:06 +1100 Subject: [PATCH 0281/1116] Change the order of release types --- .github/workflows/publish-all-operators.yaml | 4 ++-- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 8 ++++---- .github/workflows/publish-azure-cc-enclave-docker.yaml | 6 +++--- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 6 +++--- .../workflows/publish-public-operator-docker-image.yaml | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 79a09657a..242049fab 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -7,9 +7,9 @@ on: type: choice description: The type of release options: - - Major - - Minor - Patch + - Minor + - Major vulnerability_severity: description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). type: string diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 75fdf8061..164636f09 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -7,10 +7,10 @@ on: type: choice description: The type of release options: - - Major - - Minor - - Patch - - Snapshot + - Snapshot + - Patch + - Minor + - Major version_number_input: description: If set, the version number will not be incremented and the given number will be used. type: string diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 06a093001..1837b6259 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -7,10 +7,10 @@ on: type: choice description: The type of release options: - - Major - - Minor - - Patch - Snapshot + - Patch + - Minor + - Major version_number_input: description: If set, the version number will not be incremented and the given number will be used. type: string diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 8bd7980b3..039c299f7 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -7,10 +7,10 @@ on: type: choice description: The type of release options: - - Major - - Minor - - Patch - Snapshot + - Patch + - Minor + - Major version_number_input: description: If set, the version number will not be incremented and the given number will be used. type: string diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 5258d3570..65cd0f5e3 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -7,10 +7,10 @@ on: type: choice description: The type of release options: - - Major - - Minor - - Patch - Snapshot + - Patch + - Minor + - Major version_number_input: description: If set, the version number will not be incremented and the given number will be used. type: string From 3c8d22dc4b5e7b52e9d30fed3c9fec45661325d2 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 12:48:34 +1100 Subject: [PATCH 0282/1116] Adding manual approval step --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 164636f09..f2ecd6015 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -35,6 +35,15 @@ jobs: name: Build Image runs-on: ubuntu-latest steps: + - name: Approve Major release + if: inputs.release_type == 'Major' + uses: trstringer/manual-approval@v1 + with: + secret: ${{ github.token }} + approvers: thomasm-ttd,atarassov-ttd,cody-constine-ttd + minimum-approvals: 1 + issue-title: Creating Major version of UID2-Operator + - name: Check branch and release type id: checkRelease uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 From 91a079657f821499e7b84162d7c14b0e75f08aaa Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 13:03:56 +1100 Subject: [PATCH 0283/1116] Add approval step for major release --- .github/workflows/publish-all-operators.yaml | 9 +++++++++ .../publish-aws-nitro-enclave-docker.yaml | 12 ++++++------ .../workflows/publish-azure-cc-enclave-docker.yaml | 9 +++++++++ .../workflows/publish-gcp-oidc-enclave-docker.yaml | 10 ++++++++++ .../publish-public-operator-docker-image.yaml | 14 ++++++++++++++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 242049fab..f4f41eda8 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -22,6 +22,15 @@ jobs: outputs: new_version: ${{ steps.version.outputs.new_version }} steps: + - name: Approve Major release + if: inputs.release_type == 'Major' + uses: trstringer/manual-approval@v1 + with: + secret: ${{ github.token }} + approvers: thomasm-ttd,atarassov-ttd,cody-constine-ttd + minimum-approvals: 1 + issue-title: Creating Major version of UID2-Operator + - name: Show Context run: | printenv diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index f2ecd6015..a97073fb5 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -35,6 +35,12 @@ jobs: name: Build Image runs-on: ubuntu-latest steps: + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + with: + release_type: ${{ inputs.release_type }} + - name: Approve Major release if: inputs.release_type == 'Major' uses: trstringer/manual-approval@v1 @@ -44,12 +50,6 @@ jobs: minimum-approvals: 1 issue-title: Creating Major version of UID2-Operator - - name: Check branch and release type - id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 - with: - release_type: ${{ inputs.release_type }} - - name: Free up space - delete preinstalled tools run: | rm -rf /opt/hostedtoolcache diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 1837b6259..a6dd09df0 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -63,6 +63,15 @@ jobs: jar_version: ${{ steps.version.outputs.new_version }} image_tag: ${{ steps.updatePom.outputs.image_tag }} steps: + - name: Approve Major release + if: inputs.release_type == 'Major' + uses: trstringer/manual-approval@v1 + with: + secret: ${{ github.token }} + approvers: thomasm-ttd,atarassov-ttd,cody-constine-ttd + minimum-approvals: 1 + issue-title: Creating Major version of UID2-Operator + - name: Check branch and release type id: checkRelease uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2 diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 039c299f7..d8e61e2a5 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -64,6 +64,16 @@ jobs: jar_version: ${{ steps.version.outputs.new_version }} image_tag: ${{ steps.updatePom.outputs.image_tag }} steps: + + - name: Approve Major release + if: inputs.release_type == 'Major' + uses: trstringer/manual-approval@v1 + with: + secret: ${{ github.token }} + approvers: thomasm-ttd,atarassov-ttd,cody-constine-ttd + minimum-approvals: 1 + issue-title: Creating Major version of UID2-Operator + - name: Check branch and release type id: checkRelease uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 65cd0f5e3..320919b10 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -41,9 +41,23 @@ on: value: ${{ jobs.Image.outputs.image_tag }} jobs: + check_major: + name: Check if major release + runs-on: ubuntu-latest + steps: + - name: Approve Major release + if: inputs.release_type == 'Major' + uses: trstringer/manual-approval@v1 + with: + secret: ${{ github.token }} + approvers: thomasm-ttd,atarassov-ttd,cody-constine-ttd + minimum-approvals: 1 + issue-title: Creating Major version of UID2-Operator + image: name: Image uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-publish-java-to-docker-versioned.yaml@v2 + needs: check_major with: release_type: ${{ inputs.release_type }} version_number_input: ${{ inputs.version_number_input }} From 038b179c542948f01a93df78877a4e08a46d3018 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 20 Mar 2024 02:12:50 +0000 Subject: [PATCH 0284/1116] [CI Pipeline] Released Patch version: 5.28.62-fae94e5bf6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5899bb871..b37e5f010 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.57-SNAPSHOT + 5.28.62-fae94e5bf6 UTF-8 From 9cbef6658f57ccbafca3ecb698ba2593e805ffd8 Mon Sep 17 00:00:00 2001 From: Alex Yau Date: Wed, 20 Mar 2024 13:58:39 +1100 Subject: [PATCH 0285/1116] Address CVE-2023-52425 vulnerability --- .trivyignore | 3 --- Dockerfile | 3 ++- README.md | 9 ++++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.trivyignore b/.trivyignore index 3df38b54c..3aa85f54a 100644 --- a/.trivyignore +++ b/.trivyignore @@ -3,6 +3,3 @@ # for more details # e.g. # CVE-2022-3996 - -# https://atlassian.thetradedesk.com/jira/browse/UID2-2927 -CVE-2023-52425 diff --git a/Dockerfile b/Dockerfile index 9e64d2deb..0318961b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM eclipse-temurin@sha256:d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/11.0.22_7-jre-alpine/images/sha256-d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a?context=explore +FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 WORKDIR /app EXPOSE 8080 diff --git a/README.md b/README.md index 9b4807294..4cab735c7 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,14 @@ mvn clean compile exec:java -Dvertx-config-path=conf/local-config.json mvn clean compile exec:java -Dvertx-config-path=conf/integ-config.json ``` ## Local deployment/testing on Docker -1. Change `COPY ./conf/default-config.json /app/conf/` in line 13 of `Dockerfile` to `COPY ./conf/docker-config.json /app/conf/local-config.json` +1. In [Dockerfile](Dockerfile), change the line + ``` + COPY ./conf/default-config.json /app/conf/ + ``` + to: + ``` + COPY ./conf/docker-config.json /app/conf/local-config.json + ``` 2. Run ```mvn package``` 3. Go to `pom.xml` and find the version wrapped under `` tag 4. Run ```docker build -t uid2-operator --build-arg JAR_VERSION={version you find in step 3} .``` From 3389189e335ec7f4a2dd05192b7fee2d8f37a78f Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 14:13:00 +1100 Subject: [PATCH 0286/1116] Updating the files created for the release --- .github/workflows/publish-all-operators.yaml | 39 ++++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index f4f41eda8..c7311ca34 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -115,8 +115,8 @@ jobs: version_number_input: ${{ needs.start.outputs.new_version }} secrets: inherit - collectAllArtifacts: - name: Collect All Artifacts + createRelease: + name: Create Release runs-on: ubuntu-latest needs: [start, buildPublic, buildGCP, buildAzure, buildAWS] steps: @@ -129,32 +129,33 @@ jobs: - name: Download GCP manifest uses: actions/download-artifact@v4 with: - pattern: enclave_id* + pattern: gcp-oidc-enclave-ids-* path: ./manifests/gcp_oidc_operator - name: Download Azure manifest uses: actions/download-artifact@v4 with: - pattern: azure-cc-operator-digest* + pattern: azure-cc-enclave-id-* path: ./manifests/azure_cc_operator - name: Download AWS manifest uses: actions/download-artifact@v4 with: - pattern: 'aws-enclave-id*' + pattern: 'aws-enclave-ids-*' path: ./manifests/aws_nitro_operator + - name: Download Deployment Files + uses: actions/download-artifact@v4 + with: + pattern: '*-deployment-files-*' + path: ./deployment + - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests path: ./manifests - release: - name: Create Release - runs-on: ubuntu-latest - needs: [start, collectAllArtifacts] - steps: - name: Build changelog id: changelog uses: mikepenz/release-changelog-builder-action@v4 @@ -168,11 +169,25 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Zip files + run: | + zip -j ./aws-euid-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/aws-euid-deployment-files-${{ needs.start.outputs.new_version }}/* + zip -j ./aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}/* + zip -j ./azure-cc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/azure-cc-deployment-files-${{ needs.start.outputs.new_version }}/* + zip -j ./gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}/* + zip -j ./uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests.zip ./manifests/* + + - name: Create draft release uses: softprops/action-gh-release@v2 with: - name: ${{ needs.start.outputs.new_version }} + name: v${{ needs.start.outputs.new_version }} body: ${{ steps.changelog.outputs.changelog }} draft: true files: | - ./artifacts/uid2-operator-release-${{ needs.start.outputs.new_version }}.zip + ./aws-euid-deployment-files-${{ needs.start.outputs.new_version }}.zip + ./aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}.zip + ./azure-cc-deployment-files-${{ needs.start.outputs.new_version }}.zip + ./gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}.zip + ./uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests.zip + From 9fbc5869f7879f6eede88e02f056e1b9c15fd313 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 20 Mar 2024 03:15:12 +0000 Subject: [PATCH 0287/1116] [CI Pipeline] Released Patch version: 5.28.65-e0b74c35ee --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b37e5f010..d1faadd69 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.62-fae94e5bf6 + 5.28.65-e0b74c35ee UTF-8 From 3a70e8852cc6a8864aa856abe0d0c05b21101508 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 14:46:37 +1100 Subject: [PATCH 0288/1116] Updated the zip file for the manifests --- .github/workflows/publish-all-operators.yaml | 3 +-- .github/workflows/publish-public-operator-docker-image.yaml | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index c7311ca34..68b7357e8 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -175,9 +175,8 @@ jobs: zip -j ./aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}/* zip -j ./azure-cc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/azure-cc-deployment-files-${{ needs.start.outputs.new_version }}/* zip -j ./gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}/* - zip -j ./uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests.zip ./manifests/* + (cd manifests && zip -r ../uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests.zip .) - - name: Create draft release uses: softprops/action-gh-release@v2 with: diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 320919b10..6c2328112 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -74,10 +74,10 @@ jobs: operator_image_version: ${{ needs.image.outputs.image_tag }} secrets: inherit - collectAllArtifacts: - name: Collect All Artifacts + collectPublicArtifacts: + name: Collect Public Artifacts runs-on: ubuntu-latest - needs: [image, e2e] + needs: [e2e] steps: - name: Collect artifacts run: | From dbb4ea0aaa4948bdcbbaf932a91c37fc8f4d1d20 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 20 Mar 2024 03:48:13 +0000 Subject: [PATCH 0289/1116] [CI Pipeline] Released Patch version: 5.28.69-7731e915a3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1faadd69..eb5eba217 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.65-e0b74c35ee + 5.28.69-7731e915a3 UTF-8 From f8ddb68a80a2d85fb87d103855c5f38e94bfba5d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 20 Mar 2024 15:16:52 +1100 Subject: [PATCH 0290/1116] Added missing dependency --- .github/workflows/publish-all-operators.yaml | 5 ++--- .github/workflows/publish-public-operator-docker-image.yaml | 2 +- .github/workflows/run-e2e-tests-on-operator.yaml | 6 ++---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 68b7357e8..73df6cc12 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -175,7 +175,7 @@ jobs: zip -j ./aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}/* zip -j ./azure-cc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/azure-cc-deployment-files-${{ needs.start.outputs.new_version }}/* zip -j ./gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./deployment/gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}/* - (cd manifests && zip -r ../uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests.zip .) + (cd manifests && zip -r ../uid2-operator-release-manifests-${{ needs.start.outputs.new_version }}.zip .) - name: Create draft release uses: softprops/action-gh-release@v2 @@ -188,5 +188,4 @@ jobs: ./aws-uid2-deployment-files-${{ needs.start.outputs.new_version }}.zip ./azure-cc-deployment-files-${{ needs.start.outputs.new_version }}.zip ./gcp-oidc-deployment-files-${{ needs.start.outputs.new_version }}.zip - ./uid2-operator-release-${{ needs.start.outputs.new_version }}-manifests.zip - + ./uid2-operator-release-manifests-${{ needs.start.outputs.new_version }}.zip diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 6c2328112..c47a675cf 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -77,7 +77,7 @@ jobs: collectPublicArtifacts: name: Collect Public Artifacts runs-on: ubuntu-latest - needs: [e2e] + needs: [e2e,image] steps: - name: Collect artifacts run: | diff --git a/.github/workflows/run-e2e-tests-on-operator.yaml b/.github/workflows/run-e2e-tests-on-operator.yaml index 05f7b4eef..f935fd433 100644 --- a/.github/workflows/run-e2e-tests-on-operator.yaml +++ b/.github/workflows/run-e2e-tests-on-operator.yaml @@ -53,8 +53,7 @@ on: default: '{ "region": "us-east-1", "ami": "ami-xxxxx", - "pcr0": "xxxxx" - }' + "pcr0": "xxxxx" }' workflow_call: inputs: @@ -100,8 +99,7 @@ on: default: '{ "region": "us-east-1", "ami": "ami-xxxxx", - "pcr0": "xxxxx" - }' + "pcr0": "xxxxx" }' jobs: e2e-test: From 4624d3b4ac31224982f23c699833942ef4d8293c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 20 Mar 2024 04:19:17 +0000 Subject: [PATCH 0291/1116] [CI Pipeline] Released Patch version: 5.28.73-e188fe909f --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eb5eba217..b4747ab1b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.69-7731e915a3 + 5.28.73-e188fe909f UTF-8 From d124edce22eb6a4c7c184dd9ae41f9bf3d0ecbd8 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Thu, 21 Mar 2024 13:26:17 +1100 Subject: [PATCH 0292/1116] Scan for high vulnerability (#451) --- .github/workflows/build-and-test.yaml | 2 +- .github/workflows/check-stable-dependency.yaml | 2 +- .github/workflows/publish-all-operators.yaml | 4 ++-- .../workflows/publish-aws-nitro-enclave-docker.yaml | 6 +++--- .../workflows/publish-azure-cc-enclave-docker.yaml | 12 ++++++------ .../workflows/publish-gcp-oidc-enclave-docker.yaml | 12 ++++++------ .../publish-public-operator-docker-image.yaml | 8 ++++---- .github/workflows/validate-image.yaml | 6 +++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index 7d13279b6..4aad7e54c 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -3,5 +3,5 @@ on: [pull_request, push, workflow_dispatch] jobs: build: - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-build-and-test.yaml@main + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-build-and-test.yaml@v2 secrets: inherit \ No newline at end of file diff --git a/.github/workflows/check-stable-dependency.yaml b/.github/workflows/check-stable-dependency.yaml index 9839fa632..f8a417b55 100644 --- a/.github/workflows/check-stable-dependency.yaml +++ b/.github/workflows/check-stable-dependency.yaml @@ -3,5 +3,5 @@ on: [pull_request, workflow_dispatch] jobs: check_dependency: - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-check-stable-dependency.yaml@main + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-check-stable-dependency.yaml@v2 secrets: inherit \ No newline at end of file diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 73df6cc12..05fc05ae7 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -11,9 +11,9 @@ on: - Minor - Major vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' jobs: start: diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index a97073fb5..302f8dd43 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -83,7 +83,7 @@ jobs: - name: Set version number id: version - uses: IABTechLab/uid2-shared-actions/actions/version_number@main + uses: IABTechLab/uid2-shared-actions/actions/version_number@v2 with: type: ${{ inputs.release_type }} version_number: ${{ inputs.version_number_input }} @@ -115,7 +115,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@v2 with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -129,7 +129,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@v2 with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index a6dd09df0..ab46137a5 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -16,9 +16,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' workflow_call: inputs: @@ -31,9 +31,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' outputs: image_tag: @@ -113,7 +113,7 @@ jobs: - name: Set version number id: version - uses: IABTechLab/uid2-shared-actions/actions/version_number@main + uses: IABTechLab/uid2-shared-actions/actions/version_number@v2 with: type: ${{ inputs.release_type }} version_number: ${{ inputs.version_number_input }} @@ -185,7 +185,7 @@ jobs: format: 'sarif' exit-code: '0' ignore-unfixed: true - severity: 'CRITICAL,HIGH' + severity: 'HIGH' output: 'trivy-results.sarif' hide-progress: true diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index d8e61e2a5..14e13d984 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -16,9 +16,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' workflow_call: inputs: release_type: @@ -30,9 +30,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' outputs: image_tag: @@ -115,7 +115,7 @@ jobs: - name: Set version number id: version - uses: IABTechLab/uid2-shared-actions/actions/version_number@main + uses: IABTechLab/uid2-shared-actions/actions/version_number@v2 with: type: ${{ inputs.release_type }} version_number: ${{ inputs.version_number_input }} @@ -221,7 +221,7 @@ jobs: format: 'sarif' exit-code: '0' ignore-unfixed: true - severity: 'CRITICAL,HIGH' + severity: 'HIGH' output: 'trivy-results.sarif' hide-progress: true diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index c47a675cf..03d3474e8 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -16,9 +16,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' workflow_call: inputs: @@ -31,9 +31,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. type: string - default: 'CRITICAL,HIGH' + default: 'HIGH' outputs: image_tag: diff --git a/.github/workflows/validate-image.yaml b/.github/workflows/validate-image.yaml index e68a5b5d5..184d401f6 100644 --- a/.github/workflows/validate-image.yaml +++ b/.github/workflows/validate-image.yaml @@ -16,14 +16,14 @@ on: jobs: build-publish-docker-default: - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@main + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 with: failure_severity: ${{ inputs.failure_severity || 'HIGH'}} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'default' secrets: inherit build-publish-docker-aws: - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@main + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 with: failure_severity: ${{ inputs.failure_severity || 'HIGH'}} fail_on_error: ${{ inputs.fail_on_error || true }} @@ -31,7 +31,7 @@ jobs: secrets: inherit needs: [build-publish-docker-default] build-publish-docker-gcp: - uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@main + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 with: failure_severity: ${{ inputs.failure_severity || 'HIGH'}} fail_on_error: ${{ inputs.fail_on_error || true }} From f8fcc3e06ac9d445b0680be4b58cf8e69ba4bfd8 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Thu, 21 Mar 2024 16:46:48 +1100 Subject: [PATCH 0293/1116] Revert "Scan for high vulnerability" (#452) * Revert "Scan for high vulnerability (#451)" This reverts commit d124edce22eb6a4c7c184dd9ae41f9bf3d0ecbd8. * Replace main with v2 * Update severity to choice --- .github/workflows/publish-all-operators.yaml | 9 ++++++--- .../publish-azure-cc-enclave-docker.yaml | 15 +++++++++------ .../publish-gcp-oidc-enclave-docker.yaml | 15 +++++++++------ .../publish-public-operator-docker-image.yaml | 13 ++++++++----- .github/workflows/validate-image.yaml | 17 ++++++++++------- 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 05fc05ae7..3bc13d34e 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -11,9 +11,12 @@ on: - Minor - Major vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. - type: string - default: 'HIGH' + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. + type: choice + options: + - CRITICAL,HIGH + - CRITICAL,HIGH,MEDIUM + - CRITICAL (DO NOT use if JIRA ticket not raised) jobs: start: diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index ab46137a5..5d983fb28 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -16,9 +16,12 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. - type: string - default: 'HIGH' + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. + type: choice + options: + - CRITICAL,HIGH + - CRITICAL,HIGH,MEDIUM + - CRITICAL (DO NOT use if JIRA ticket not raised) workflow_call: inputs: @@ -31,9 +34,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). type: string - default: 'HIGH' + default: 'CRITICAL,HIGH' outputs: image_tag: @@ -185,7 +188,7 @@ jobs: format: 'sarif' exit-code: '0' ignore-unfixed: true - severity: 'HIGH' + severity: 'CRITICAL,HIGH' output: 'trivy-results.sarif' hide-progress: true diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 14e13d984..797c3e61b 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -16,9 +16,12 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. - type: string - default: 'HIGH' + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. + type: choice + options: + - CRITICAL,HIGH + - CRITICAL,HIGH,MEDIUM + - CRITICAL (DO NOT use if JIRA ticket not raised) workflow_call: inputs: release_type: @@ -30,9 +33,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). type: string - default: 'HIGH' + default: 'CRITICAL,HIGH' outputs: image_tag: @@ -221,7 +224,7 @@ jobs: format: 'sarif' exit-code: '0' ignore-unfixed: true - severity: 'HIGH' + severity: 'CRITICAL,HIGH' output: 'trivy-results.sarif' hide-progress: true diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 03d3474e8..050b75bcc 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -16,9 +16,12 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. - type: string - default: 'HIGH' + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. + type: choice + options: + - CRITICAL,HIGH + - CRITICAL,HIGH,MEDIUM + - CRITICAL (DO NOT use if JIRA ticket not raised) workflow_call: inputs: @@ -31,9 +34,9 @@ on: type: string default: '' vulnerability_severity: - description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'HIGH' or 'MEDIUM']. + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. Must be one of ['CRITICAL', 'CRITICAL,HIGH' or 'CRITICAL,HIGH,MEDIUM'] (without space in between). type: string - default: 'HIGH' + default: 'CRITICAL,HIGH' outputs: image_tag: diff --git a/.github/workflows/validate-image.yaml b/.github/workflows/validate-image.yaml index 184d401f6..9f96a0be0 100644 --- a/.github/workflows/validate-image.yaml +++ b/.github/workflows/validate-image.yaml @@ -3,11 +3,14 @@ on: workflow_dispatch: inputs: failure_severity: - description: 'Must be one of CRITICAL, HIGH, MEDIUM' - required: false - default: 'HIGH' + description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised. + type: choice + options: + - CRITICAL,HIGH + - CRITICAL,HIGH,MEDIUM + - CRITICAL (DO NOT use if JIRA ticket not raised) fail_on_error: - description: 'If true, will fail the build if vulnerabilities are found' + description: If true, will fail the build if vulnerabilities are found required: true type: boolean default: true @@ -18,14 +21,14 @@ jobs: build-publish-docker-default: uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 with: - failure_severity: ${{ inputs.failure_severity || 'HIGH'}} + failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'default' secrets: inherit build-publish-docker-aws: uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 with: - failure_severity: ${{ inputs.failure_severity || 'HIGH'}} + failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'aws' secrets: inherit @@ -33,7 +36,7 @@ jobs: build-publish-docker-gcp: uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 with: - failure_severity: ${{ inputs.failure_severity || 'HIGH'}} + failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'gcp' secrets: inherit From 6bbf986729b27cff5970da4f956d2835c9da0c92 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 26 Mar 2024 12:46:33 +1100 Subject: [PATCH 0294/1116] Use proper branch name (#461) --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 302f8dd43..cbd9e559c 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -37,7 +37,7 @@ jobs: steps: - name: Check branch and release type id: checkRelease - uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2.2.2 + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2 with: release_type: ${{ inputs.release_type }} @@ -115,7 +115,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@v2 + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -129,7 +129,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@v2 + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 70bfb681558c68fd4dc494356a80de3bdcf820b2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 26 Mar 2024 01:47:21 +0000 Subject: [PATCH 0295/1116] [CI Pipeline] Released Patch version: 5.28.79-6bbf986729 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b4747ab1b..9fd186faa 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.73-e188fe909f + 5.28.79-6bbf986729 UTF-8 From a2cf39f96ea7c73a146aac06944200e5e1ca68df Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 27 Mar 2024 10:06:25 +1100 Subject: [PATCH 0296/1116] UID2-2889 Add unit tests for the logs (#450) * Add unit tests for the logs * Add comments on why we pass in clock to the constructor * Add tests to make sure no throwables are logged --- .../uid2/operator/service/V2RequestUtil.java | 8 +- .../uid2/operator/vertx/V2PayloadHandler.java | 7 +- .../com/uid2/operator/MemoryAppender.java | 54 +++++++++ .../com/uid2/operator/V2RequestUtilTest.java | 103 +++++++++++++++++- 4 files changed, 162 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/uid2/operator/MemoryAppender.java diff --git a/src/main/java/com/uid2/operator/service/V2RequestUtil.java b/src/main/java/com/uid2/operator/service/V2RequestUtil.java index 16f4347a7..d9737323b 100644 --- a/src/main/java/com/uid2/operator/service/V2RequestUtil.java +++ b/src/main/java/com/uid2/operator/service/V2RequestUtil.java @@ -3,6 +3,7 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.KeyManager; import com.uid2.operator.vertx.ClientInputValidationException; +import com.uid2.shared.IClock; import com.uid2.shared.Utils; import com.uid2.shared.auth.ClientKey; import com.uid2.shared.encryption.AesGcm; @@ -54,7 +55,8 @@ public boolean isValid() { private static final Logger LOGGER = LoggerFactory.getLogger(V2RequestUtil.class); - public static V2Request parseRequest(String bodyString, ClientKey ck) { + // clock is passed in to test V2_REQUEST_TIMESTAMP_DRIFT_THRESHOLD_IN_MINUTES in unit tests + public static V2Request parseRequest(String bodyString, ClientKey ck, IClock clock) { if (bodyString == null) { return new V2Request("Invalid body: Body is missing."); } @@ -91,7 +93,7 @@ public static V2Request parseRequest(String bodyString, ClientKey ck) { // byte 16-end: base64 encoded request json Buffer b = Buffer.buffer(decryptedBody); Instant tm = Instant.ofEpochMilli(b.getLong(0)); - if (Math.abs(Duration.between(tm, Clock.systemUTC().instant()).toMinutes()) > + if (Math.abs(Duration.between(tm, clock.now()).toMinutes()) > V2_REQUEST_TIMESTAMP_DRIFT_THRESHOLD_IN_MINUTES) { return new V2Request("Invalid timestamp: Request too old or client time drift."); } @@ -103,7 +105,7 @@ public static V2Request parseRequest(String bodyString, ClientKey ck) { String bodyStr = new String(decryptedBody, 16, decryptedBody.length - 16, StandardCharsets.UTF_8); payload = new JsonObject(bodyStr); } catch (Exception ex) { - LOGGER.error("Invalid payload in body: Data is not valid json string.", ex); + LOGGER.error("Invalid payload in body: Data is not valid json string."); return new V2Request("Invalid payload in body: Data is not valid json string."); } } diff --git a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java index f6ba02c5d..e59e49619 100644 --- a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java +++ b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java @@ -6,6 +6,7 @@ import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.ResponseUtil; import com.uid2.operator.service.V2RequestUtil; +import com.uid2.shared.InstantClock; import com.uid2.shared.Utils; import com.uid2.shared.auth.ClientKey; import com.uid2.shared.encryption.AesGcm; @@ -48,7 +49,7 @@ public void handle(RoutingContext rc, Handler apiHandler) { return; } - V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc)); + V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc), new InstantClock()); if (!request.isValid()) { ResponseUtil.ClientError(rc, request.errorMessage); return; @@ -66,7 +67,7 @@ public void handleAsync(RoutingContext rc, Function apiH return; } - V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc)); + V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc), new InstantClock()); if (!request.isValid()) { ResponseUtil.ClientError(rc, request.errorMessage); return; @@ -84,7 +85,7 @@ public void handleTokenGenerate(RoutingContext rc, Handler apiHa return; } - V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc)); + V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc), new InstantClock()); if (!request.isValid()) { SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); return; diff --git a/src/test/java/com/uid2/operator/MemoryAppender.java b/src/test/java/com/uid2/operator/MemoryAppender.java new file mode 100644 index 000000000..4c88e8c16 --- /dev/null +++ b/src/test/java/com/uid2/operator/MemoryAppender.java @@ -0,0 +1,54 @@ +package com.uid2.operator; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; + +public class MemoryAppender extends ListAppender { + public void reset() { + this.list.clear(); + } + + public boolean contains(String string, Level level) { + return this.list.stream() + .anyMatch(event -> event.toString().contains(string) + && event.getLevel().equals(level)); + } + + public int countEventsForLogger(String loggerName) { + return (int) this.list.stream() + .filter(event -> event.getLoggerName().contains(loggerName)) + .count(); + } + + public List search(String string) { + return this.list.stream() + .filter(event -> event.toString().equals(string)) + .collect(Collectors.toList()); + } + + public List checkNoThrowableLogged() { + return this.list.stream() + .filter(event -> event.getThrowableProxy() == null) + .collect(Collectors.toList()); + } + + public List search(String string, Level level) { + return this.list.stream() + .filter(event -> event.toString().contains(string) + && event.getLevel().equals(level)) + .collect(Collectors.toList()); + } + + public int getSize() { + return this.list.size(); + } + + public List getLoggedEvents() { + return Collections.unmodifiableList(this.list); + } +} \ No newline at end of file diff --git a/src/test/java/com/uid2/operator/V2RequestUtilTest.java b/src/test/java/com/uid2/operator/V2RequestUtilTest.java index b0eab20a4..008583cb8 100644 --- a/src/test/java/com/uid2/operator/V2RequestUtilTest.java +++ b/src/test/java/com/uid2/operator/V2RequestUtilTest.java @@ -1,26 +1,121 @@ package com.uid2.operator; import com.uid2.operator.service.V2RequestUtil; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import com.uid2.shared.IClock; +import com.uid2.shared.auth.ClientKey; +import io.vertx.core.json.JsonObject; import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.slf4j.LoggerFactory; -import static org.junit.jupiter.api.Assertions.assertEquals; +import java.time.Instant; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; public class V2RequestUtilTest { + private static final String LOGGER_NAME = "com.uid2.operator.service.V2RequestUtil"; + private static MemoryAppender memoryAppender; + private IClock clock = mock(IClock.class); + private Instant mockNow = Instant.parse("2024-03-20T04:02:46.130Z"); + + public void setupMemoryAppender() { + Logger logger = (Logger)LoggerFactory.getLogger(LOGGER_NAME); + memoryAppender = new MemoryAppender(); + memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); + logger.setLevel(Level.DEBUG); + logger.addAppender(memoryAppender); + memoryAppender.start(); + } + + @AfterEach + public void close() { + memoryAppender.reset(); + memoryAppender.stop(); + } + + @Test + public void testParseRequestWithExpectedJson() { + when(clock.now()).thenReturn(mockNow); + String testToken = "AdvertisingTokenmZ4dZgeuXXl6DhoXqbRXQbHlHhA96leN94U1uavZVspwKXlfWETZ3b%2FbesPFFvJxNLLySg4QEYHUAiyUrNncgnm7ppu0mi6wU2CW6hssiuEkKfstbo9XWgRUbWNTM%2BewMzXXM8G9j8Q%3D"; + String testEmailHash = "LdhtUlMQ58ZZy5YUqGPRQw5xUMS5dXG5ocJHYJHbAKI="; + JsonObject expectedPayload = new JsonObject(); + expectedPayload.put("token", testToken); + expectedPayload.put("email_hash", testEmailHash); + // The bodyString was encoded by below json: + // { + // "token": "AdvertisingTokenmZ4dZgeuXXl6DhoXqbRXQbHlHhA96leN94U1uavZVspwKXlfWETZ3b%2FbesPFFvJxNLLySg4QEYHUAiyUrNncgnm7ppu0mi6wU2CW6hssiuEkKfstbo9XWgRUbWNTM%2BewMzXXM8G9j8Q%3D", + // "email_hash": "LdhtUlMQ58ZZy5YUqGPRQw5xUMS5dXG5ocJHYJHbAKI=" + //} + String bodyString = "ATDX9gBKxgQaLwUi9ZDbSqo1b66u55jEN322XSR+aCvOy/c3ZiaVOh8VG22pDUSSNaUqfUwwxxYT0pS9zjW7oVPCeluHU5GCc+6A+LUTIQ8vOR+1CN7ds/61Bp82RzKf5wPABMNtqr1XkoN6d5FU/R0vpxf2hfo1cYYmW0ziCy15pPh17GN2vNTn6YK6g+MAi/dDC7mG+Mxnh9ZaEz+3IetgDPWfp5zHh/T3LWhDAA+2drlDn8KwcQE/TYKh5raR4BDHmhgBUCU6+nymoWruNYxzcII63xMTLMTGzpinNnTL3iBPII9lKRJJ2ZrGjjgMMXi066iaDDpBHH3xY+bAwriU+6GEsE8bveRMwRqT83gmkYp6mn+75Yrpdw=="; + ClientKey ck = new ClientKey( + "hash", + "salt", + "YGdzZw9oM2RzBgB8THMyAEe408lvdfsTsGteaLAGayY=", + "name", + "contact", + mockNow, + Set.of(), + 113, + false, + "key-id" + ); + V2RequestUtil.V2Request res = V2RequestUtil.parseRequest(bodyString, ck, clock); + assertEquals(expectedPayload, res.payload); + } @Test public void testParseRequestWithNullBody() { - V2RequestUtil.V2Request res = V2RequestUtil.parseRequest(null, null); + when(clock.now()).thenReturn(mockNow); + V2RequestUtil.V2Request res = V2RequestUtil.parseRequest(null, null, clock); assertEquals("Invalid body: Body is missing.", res.errorMessage); } @Test public void testParseRequestWithNonBase64Body() { - V2RequestUtil.V2Request res = V2RequestUtil.parseRequest("test string", null); + when(clock.now()).thenReturn(mockNow); + V2RequestUtil.V2Request res = V2RequestUtil.parseRequest("test string", null, clock); assertEquals("Invalid body: Body is not valid base64.", res.errorMessage); } @Test public void testParseRequestWithTooShortBody() { - V2RequestUtil.V2Request res = V2RequestUtil.parseRequest("dGVzdA==", null); + when(clock.now()).thenReturn(mockNow); + V2RequestUtil.V2Request res = V2RequestUtil.parseRequest("dGVzdA==", null, clock); assertEquals("Invalid body: Body too short. Check encryption method.", res.errorMessage); } + + @Test + public void testParseRequestWithMalformedJson() { + setupMemoryAppender(); + when(clock.now()).thenReturn(Instant.parse("2024-03-20T06:33:15.627Z")); + // The bodyString was encoded by below json: + // { + // "token": "AdvertisingTokenmZ4dZgeuXXl6DhoXqbRXQbHlHhA96leN94U1uavZVspwKXlfWETZ3b%2FbesPFFvJxNLLySg4QEYHUAiyUrNncgnm7ppu0mi6wU2CW6hssiuEkKfstbo9XWgRUbWNTM%2BewMzXXM8G9j8Q%3D", + // "email_hash": "LdhtUlMQ58ZZy5YUqGPRQw5xUMS5dXG5ocJHYJHbAKI=", + // test + //} + String bodyString = "AWDCc1W2zSIJUFbCF1Ti7FxS9Vq4xywgUxHWm60+aaNIbk9k1c3GLjcezo6ZGx3J9TUEKdCXLVi+t2d4T17acgSZYRhfTUC6OfxEHxzSkhDLviQ6BXqrx0Ute5PWT55FYG5dR8YM8CAUfLuWSxCq4yB+aJ/Sojpl2nmDO7sn7D6K+dAsdCtyciM+8ihxzOb7obhlOhjS5159XqkQTcAQvbfLXi/QJRtFPoDBpwQQZ3TvBFPUvh8uiT0Zb708Xt7zt9NHziqkwAcJWIvnTgLkxBdACpbGGl3mNcwJhHwBM0m9zlSy050yyx/b+U1mJxjj5yqBwaNSzTKiGHs+M1+vhmVD8w7J13Ec+jAUa8rUeN7c61GD/Rh7GndeEBo4WVLvfw=="; + ClientKey ck = new ClientKey( + "hash", + "salt", + "YGdzZw9oM2RzBgB8THMyAEe408lvdfsTsGteaLAGayY=", + "name", + "contact", + mockNow, + Set.of(), + 113, + false, + "key-id" + ); + V2RequestUtil.V2Request res = V2RequestUtil.parseRequest(bodyString, ck, clock); + assertEquals("Invalid payload in body: Data is not valid json string.", res.errorMessage); + assertThat(memoryAppender.countEventsForLogger(LOGGER_NAME)).isEqualTo(1); + assertThat(memoryAppender.search("[ERROR] Invalid payload in body: Data is not valid json string.").size()).isEqualTo(1); + assertThat(memoryAppender.checkNoThrowableLogged().size()).isEqualTo(1); + } } From 922578729e25b7923f67b4bf24d97f4f4c081a7d Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 27 Mar 2024 12:29:40 +1100 Subject: [PATCH 0297/1116] Separate UID2 and EUID EIF build steps (#453) * Separate UID2 and EUID EIF build steps * Use needs to get outputs * Use `main` instead of `v2` for `build_aws_eif` action * Test changes on kcc-UID2-2996-parallelize-eif-build * Add checkout step to all the jobs * Revert testing * Download EIFs * Add test branch checkout --- .../publish-aws-nitro-enclave-docker.yaml | 115 +++++++++++++++--- 1 file changed, 96 insertions(+), 19 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index cbd9e559c..9998c6e6a 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -31,8 +31,8 @@ env: ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts jobs: - buildImage: - name: Build Image + start: + name: Start Building AWS Image runs-on: ubuntu-latest steps: - name: Check branch and release type @@ -112,6 +112,37 @@ jobs: add: 'pom.xml version.json' message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} + outputs: + new_version: ${{ steps.version.outputs.new_version }} + is_release: ${{ steps.checkRelease.outputs.is_release }} + github_changelog: ${{ steps.github_release.outputs.changelog }} + + buildUID2EIF: + name: Build UID2 EIF + runs-on: ubuntu-latest + needs: start + steps: + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Free up space - delete preinstalled tools + run: | + rm -rf /opt/hostedtoolcache - name: Build UID2 AWS EIF id: build_uid2_eif @@ -123,10 +154,39 @@ jobs: - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: - name: aws-uid2-deployment-files-${{ steps.version.outputs.new_version }} + name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error - + outputs: + uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} + + buildEUIDEIF: + name: Build EUID EIF + runs-on: ubuntu-latest + needs: start + steps: + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Free up space - delete preinstalled tools + run: | + rm -rf /opt/hostedtoolcache + - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main @@ -137,32 +197,49 @@ jobs: - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: - name: aws-euid-deployment-files-${{ steps.version.outputs.new_version }} + name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error + outputs: + euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} + + cleanup: + name: Cleanup Building AWS Image + runs-on: ubuntu-latest + needs: [start, buildUID2EIF, buildEUIDEIF] + steps: + - name: Download UID2 artifacts + uses: actions/download-artifact@v4 + with: + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + - name: Download EUID artifacts + uses: actions/download-artifact@v4 + with: + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt + echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 with: - name: aws-enclave-ids-${{ steps.version.outputs.new_version }} + name: aws-enclave-ids-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests if-no-files-found: error - name: Generate release archive files - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} run: | - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - name: Build changelog id: github_release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v4 with: configurationJson: | @@ -174,15 +251,15 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v2 with: - name: ${{ steps.version.outputs.new_version }} - body: ${{ steps.github_release.outputs.changelog }} + name: ${{ needs.start.outputs.new_version }} + body: ${{ needs.start.outputs.github_changelog }} draft: true files: | - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt From 68fc0c717d905fd23c52876c9d0fb4efe2cc143c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 27 Mar 2024 01:33:12 +0000 Subject: [PATCH 0298/1116] [CI Pipeline] Released Patch version: 5.28.83-922578729e --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9fd186faa..6479932d3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.79-6bbf986729 + 5.28.83-922578729e UTF-8 From 1ae3b128c15b0fb76d37498517fc55880292656d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 4 Apr 2024 10:55:23 +1100 Subject: [PATCH 0299/1116] Add syslog-ng to eif --- .github/actions/build_aws_eif/action.yaml | 1 + scripts/aws/Dockerfile | 3 +- scripts/aws/conf/logback.loki.xml | 10 +++++++ scripts/aws/entrypoint.sh | 6 ++++ scripts/aws/proxies.host.yaml | 7 ++++- scripts/aws/proxies.nitro.yaml | 7 ++++- scripts/aws/start.sh | 6 ++++ scripts/aws/syslog-ng/syslog-ng-client.conf | 16 ++++++++++ scripts/aws/syslog-ng/syslog-ng-server.conf | 33 +++++++++++++++++++++ 9 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 scripts/aws/syslog-ng/syslog-ng-client.conf create mode 100644 scripts/aws/syslog-ng/syslog-ng-server.conf diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 7f3a0d4c0..3a81d9dce 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -65,6 +65,7 @@ runs: cp ./scripts/aws/sockd.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/VERSION + cp ./scripts/aws/syslog-ng/syslog-ng-server.conf ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index b52827223..e01b6ea7b 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -15,7 +15,7 @@ ENV ENCLAVE_ENVIRONMENT="aws-nitro" ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" RUN apt update -y \ - && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip \ + && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip syslog-ng \ && rm -rf /var/lib/apt/lists/* RUN pip3 install boto3==1.16.9 @@ -33,6 +33,7 @@ COPY ./conf/integ-uid2-config.json /app/conf/ COPY ./conf/prod-euid-config.json /app/conf/ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ +COPY ./syslog-ng/syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh diff --git a/scripts/aws/conf/logback.loki.xml b/scripts/aws/conf/logback.loki.xml index 69bc00c07..9e5879a60 100644 --- a/scripts/aws/conf/logback.loki.xml +++ b/scripts/aws/conf/logback.loki.xml @@ -13,8 +13,18 @@ true + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %ex%n + + + + \ No newline at end of file diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 54b81507c..8d14ebde9 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -11,6 +11,10 @@ ifconfig lo 127.0.0.1 echo "Starting vsock proxy..." /app/vsockpx --config /app/proxies.nitro.yaml --daemon --workers $(( $(nproc) * 2 )) --log-level 3 +# -- setup syslog-ng +echo "Starting syslog-ng..." +/usr/sbin/syslog-ng -F + # -- load env vars via proxy echo "Loading env vars via proxy..." @@ -97,6 +101,8 @@ echo "Setting up Loki..." && SETUP_LOKI_LINE="-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dlogback.configurationFile=./conf/logback.loki.xml" \ || SETUP_LOKI_LINE="" +echo "Final loki config:${SETUP_LOKI_LINE}" + HOSTNAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/local-hostname) echo "HOSTNAME=${HOSTNAME}" diff --git a/scripts/aws/proxies.host.yaml b/scripts/aws/proxies.host.yaml index f98f92710..deb691d5b 100644 --- a/scripts/aws/proxies.host.yaml +++ b/scripts/aws/proxies.host.yaml @@ -18,4 +18,9 @@ operator-prometheus: loki: service: direct listen: vsock://-1:3100 - connect: tcp://127.0.0.1:3100 \ No newline at end of file + connect: tcp://127.0.0.1:3100 + +syslogng: + service: direct + listen: vsock://-1:2010 + connect: tcp://127.0.0.1:2010 \ No newline at end of file diff --git a/scripts/aws/proxies.nitro.yaml b/scripts/aws/proxies.nitro.yaml index 5ca5635f5..d025b7c76 100644 --- a/scripts/aws/proxies.nitro.yaml +++ b/scripts/aws/proxies.nitro.yaml @@ -23,4 +23,9 @@ aws-service-proxy: loki: service: direct listen: tcp://0.0.0.0:3100 - connect: vsock://3:3100 \ No newline at end of file + connect: vsock://3:3100 + +syslogng: + service: direct + listen: tcp://0.0.0.0:2010 + connect: vsock://3:2010 \ No newline at end of file diff --git a/scripts/aws/start.sh b/scripts/aws/start.sh index 705acb80b..f5e349356 100644 --- a/scripts/aws/start.sh +++ b/scripts/aws/start.sh @@ -99,6 +99,11 @@ function run_enclave() { nitro-cli run-enclave --eif-path $EIF_PATH --memory $MEMORY_MB --cpu-count $CPU_COUNT --enclave-cid $CID --enclave-name uid2operator } +function run_syslog_ng() { + echo "starting syslog-ng..." + /usr/sbin/syslog-ng -F +} + terminate_old_enclave config_aws read_allocation @@ -106,6 +111,7 @@ read_allocation setup_vsockproxy setup_aws_proxy setup_dante +run_syslog_ng run_enclave echo "Done!" diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf new file mode 100644 index 000000000..11a09f61f --- /dev/null +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -0,0 +1,16 @@ +@version: 3.35 +@include "scl.conf" + +source s_local { + system(); + internal(); +}; + +destination d_syslog_tcp { + syslog("127.0.0.1" transport("tcp") port(2010)); +}; + +log { + source(s_local); + destination(d_syslog_tcp); +}; \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf new file mode 100644 index 000000000..a33908d46 --- /dev/null +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -0,0 +1,33 @@ +@version: 3.35 +@include "scl.conf" + +options { + keep_hostname(yes); + create_dirs(yes); + ts_format(iso); + time_reopen(10); + chain_hostnames(no); +}; + +source s_local { + system(); + internal(); +}; + +source s_network { + syslog( + ip(0.0.0.0) + port(2010) + transport("tcp") + ); +}; + +destination d_local { + file("/var/log/messages"); +}; + +log { + source(s_local); + source(s_network); + destination(d_local); +}; \ No newline at end of file From 3129c5c1555cf1cec6aa3ea41d916e11cadaf402 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 4 Apr 2024 00:00:24 +0000 Subject: [PATCH 0300/1116] [CI Pipeline] Released Snapshot version: 5.28.86-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6479932d3..447b7145b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.83-922578729e + 5.28.86-SNAPSHOT UTF-8 From fb484bee50a98c2bdb83d000a1971dc751677ce0 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 4 Apr 2024 11:18:23 +1100 Subject: [PATCH 0301/1116] Added syslog-ng conf file to docker --- Makefile.nitro | 7 +++++-- scripts/aws/Dockerfile | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile.nitro b/Makefile.nitro index 946d845cb..b25d0afba 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -13,11 +13,11 @@ all: build_eif build_eif: uid2operator.eif euidoperator.eif -uid2operator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py +uid2operator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./uid2operator.tar uid2operator; docker cp ./uid2operator.tar amazonlinux:/uid2operator.tar docker exec amazonlinux bash aws_nitro_eif.sh uid2operator -euidoperator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py +euidoperator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./euidoperator.tar euidoperator; docker cp ./euidoperator.tar amazonlinux:/euidoperator.tar docker exec amazonlinux bash aws_nitro_eif.sh euidoperator @@ -63,6 +63,9 @@ build/Dockerfile: build_artifacts ./scripts/aws/Dockerfile build/proxies.nitro.yaml: build_artifacts ./scripts/aws/proxies.nitro.yaml cp ./scripts/aws/proxies.nitro.yaml ./build/ +build/syslog-ng-client.conf: build_artifacts ./scripts/aws/syslog-ng/syslog-ng-client.conf + cp ./scripts/aws/syslog-ng/syslog-ng-client.conf ./build/ + build/entrypoint.sh: build_artifacts cp ./scripts/aws/entrypoint.sh ./build/ diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index e01b6ea7b..e30ad35d8 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -33,7 +33,7 @@ COPY ./conf/integ-uid2-config.json /app/conf/ COPY ./conf/prod-euid-config.json /app/conf/ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ -COPY ./syslog-ng/syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf +COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh From ecf6f6b367b10fe968aada2b0a348fe5014123b2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 4 Apr 2024 00:19:18 +0000 Subject: [PATCH 0302/1116] [CI Pipeline] Released Snapshot version: 5.28.88-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 447b7145b..f516d973b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.86-SNAPSHOT + 5.28.88-SNAPSHOT UTF-8 From 1b7f9d3cef89fc370dc72a40934bda1e12b59bc6 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 4 Apr 2024 16:45:37 +1100 Subject: [PATCH 0303/1116] Added name to artifact to download --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 9998c6e6a..d99d29f0e 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -211,11 +211,13 @@ jobs: - name: Download UID2 artifacts uses: actions/download-artifact@v4 with: + name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - name: Download EUID artifacts uses: actions/download-artifact@v4 with: + name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - name: Save Enclave Ids From 8062bfa059ae28df7724f958e05a4d91a6d8f9a2 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 4 Apr 2024 17:01:56 +1100 Subject: [PATCH 0304/1116] Update version of action to branch --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index d99d29f0e..79e815984 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -146,7 +146,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -189,7 +189,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From e12d6820bba5dc3b0f99bc4c17f38bdd3c1d44dc Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 4 Apr 2024 06:02:59 +0000 Subject: [PATCH 0305/1116] [CI Pipeline] Released Snapshot version: 5.28.91-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f516d973b..97a65d826 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.88-SNAPSHOT + 5.28.91-SNAPSHOT UTF-8 From 48e2f3a331dcfe188d397def2558aca422cfa4fd Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 5 Apr 2024 10:12:17 +1100 Subject: [PATCH 0306/1116] Verbose starting of syslog-ng --- scripts/aws/entrypoint.sh | 2 +- scripts/aws/start.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 8d14ebde9..d5411a981 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -13,7 +13,7 @@ echo "Starting vsock proxy..." # -- setup syslog-ng echo "Starting syslog-ng..." -/usr/sbin/syslog-ng -F +/usr/sbin/syslog-ng --verbose # -- load env vars via proxy echo "Loading env vars via proxy..." diff --git a/scripts/aws/start.sh b/scripts/aws/start.sh index f5e349356..8c5e2f8fd 100644 --- a/scripts/aws/start.sh +++ b/scripts/aws/start.sh @@ -101,7 +101,7 @@ function run_enclave() { function run_syslog_ng() { echo "starting syslog-ng..." - /usr/sbin/syslog-ng -F + /usr/sbin/syslog-ng --verbose } terminate_old_enclave From e5c8118af9f663fa1d11b068ca38afe9ce58ecee Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 4 Apr 2024 23:12:58 +0000 Subject: [PATCH 0307/1116] [CI Pipeline] Released Snapshot version: 5.28.93-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 97a65d826..8277bb339 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.91-SNAPSHOT + 5.28.93-SNAPSHOT UTF-8 From bccbf48598343b37b958bb5176db52ecccfc9c9e Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 8 Apr 2024 10:38:29 +1000 Subject: [PATCH 0308/1116] Updating syslog-ng installation After local java testing --- scripts/aws/Dockerfile | 2 ++ scripts/aws/conf/logback.loki.xml | 9 ++++++- scripts/aws/start.sh | 2 +- scripts/aws/syslog-ng/syslog-ng-client.conf | 28 ++++++++++++++++++--- scripts/aws/syslog-ng/syslog-ng-server.conf | 17 ++++++++++--- 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index e30ad35d8..460071609 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -35,6 +35,8 @@ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf +EXPOSE 2010 + RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh CMD ["/app/entrypoint.sh"] diff --git a/scripts/aws/conf/logback.loki.xml b/scripts/aws/conf/logback.loki.xml index 9e5879a60..bb2b27a9c 100644 --- a/scripts/aws/conf/logback.loki.xml +++ b/scripts/aws/conf/logback.loki.xml @@ -22,9 +22,16 @@ + + 127.0.0.1 + 2010 + SYSLOG + [%level] [%level] [%logger] [%thread] %msg %ex + - + + \ No newline at end of file diff --git a/scripts/aws/start.sh b/scripts/aws/start.sh index 8c5e2f8fd..a55a8eef5 100644 --- a/scripts/aws/start.sh +++ b/scripts/aws/start.sh @@ -104,6 +104,7 @@ function run_syslog_ng() { /usr/sbin/syslog-ng --verbose } +run_syslog_ng terminate_old_enclave config_aws read_allocation @@ -111,7 +112,6 @@ read_allocation setup_vsockproxy setup_aws_proxy setup_dante -run_syslog_ng run_enclave echo "Done!" diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 11a09f61f..336d5eb54 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -1,4 +1,4 @@ -@version: 3.35 +@version: 3.28 @include "scl.conf" source s_local { @@ -6,11 +6,33 @@ source s_local { internal(); }; +source s_syslog_udp { + syslog( + ip(0.0.0.0) + port(2010) + transport("udp") + ); +}; + +source s_stdout { + pipe("/dev/stdout"); + pipe("/dev/stderr"); +}; + destination d_syslog_tcp { - syslog("127.0.0.1" transport("tcp") port(2010)); + syslog("ngserver" port(2011) transport("tcp")); +}; +destination d_syslog_udp { + syslog("ngserver" port(2010) transport("udp")); +}; + +destination d_file { + file("/var/log/sysng.log"); }; log { source(s_local); + source(s_stdout); + source(s_syslog_udp); destination(d_syslog_tcp); -}; \ No newline at end of file +}; diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index a33908d46..2adc91950 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -2,11 +2,11 @@ @include "scl.conf" options { - keep_hostname(yes); + keep_hostname(no); create_dirs(yes); ts_format(iso); time_reopen(10); - chain_hostnames(no); + chain_hostnames(yes); }; source s_local { @@ -14,10 +14,18 @@ source s_local { internal(); }; -source s_network { +source s_network_udp { syslog( ip(0.0.0.0) port(2010) + transport("udp") + ); +}; + +source s_network_tcp { + syslog( + ip(0.0.0.0) + port(2011) transport("tcp") ); }; @@ -28,6 +36,7 @@ destination d_local { log { source(s_local); - source(s_network); + source(s_network_udp); + source(s_network_tcp); destination(d_local); }; \ No newline at end of file From 7aebcfb4b8904f229bdb4a8558ab437efc1a2227 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Apr 2024 00:40:29 +0000 Subject: [PATCH 0309/1116] [CI Pipeline] Released Snapshot version: 5.28.95-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8277bb339..bb694ff86 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.93-SNAPSHOT + 5.28.95-SNAPSHOT UTF-8 From 0cec205c38f5c0e9213010c29f35f8a89a2263a5 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 8 Apr 2024 11:40:58 +1000 Subject: [PATCH 0310/1116] Removed stdout as source in eif --- scripts/aws/syslog-ng/syslog-ng-client.conf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 336d5eb54..11668ce23 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -14,11 +14,6 @@ source s_syslog_udp { ); }; -source s_stdout { - pipe("/dev/stdout"); - pipe("/dev/stderr"); -}; - destination d_syslog_tcp { syslog("ngserver" port(2011) transport("tcp")); }; @@ -32,7 +27,6 @@ destination d_file { log { source(s_local); - source(s_stdout); source(s_syslog_udp); destination(d_syslog_tcp); }; From 4bad976df38fc94a3ee568dfd4fa7f98af039587 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Apr 2024 01:41:43 +0000 Subject: [PATCH 0311/1116] [CI Pipeline] Released Snapshot version: 5.28.97-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb694ff86..2021043fe 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.95-SNAPSHOT + 5.28.97-SNAPSHOT UTF-8 From 14f11c46afe1cc9cbcde080cae5891550c1bff50 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 8 Apr 2024 12:10:36 +1000 Subject: [PATCH 0312/1116] Updated server address for syslog-ng --- scripts/aws/syslog-ng/syslog-ng-client.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 11668ce23..130490d11 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -15,10 +15,10 @@ source s_syslog_udp { }; destination d_syslog_tcp { - syslog("ngserver" port(2011) transport("tcp")); + syslog(ip(127.0.0.1) port(2011) transport("tcp")); }; destination d_syslog_udp { - syslog("ngserver" port(2010) transport("udp")); + syslog(ip(127.0.0.1) port(2010) transport("udp")); }; destination d_file { From 13dde52da996d60b11793430fdd51c826b4e8199 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Apr 2024 02:11:33 +0000 Subject: [PATCH 0313/1116] [CI Pipeline] Released Snapshot version: 5.28.99-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2021043fe..0f9e6f447 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.97-SNAPSHOT + 5.28.99-SNAPSHOT UTF-8 From 977ef2fa40f34179dc0a603db90037ddae5e22d3 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 8 Apr 2024 13:19:37 +1000 Subject: [PATCH 0314/1116] Ip address change --- scripts/aws/syslog-ng/syslog-ng-client.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 130490d11..02d133ace 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -15,10 +15,10 @@ source s_syslog_udp { }; destination d_syslog_tcp { - syslog(ip(127.0.0.1) port(2011) transport("tcp")); + syslog(ip("127.0.0.1") port(2011) transport("tcp")); }; destination d_syslog_udp { - syslog(ip(127.0.0.1) port(2010) transport("udp")); + syslog(ip("127.0.0.1") port(2010) transport("udp")); }; destination d_file { From 197b55780f37e3e26a7fc9aab37309809f0a61a9 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Apr 2024 03:20:58 +0000 Subject: [PATCH 0315/1116] [CI Pipeline] Released Snapshot version: 5.28.101-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f9e6f447..2dd4ea9b4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.99-SNAPSHOT + 5.28.101-SNAPSHOT UTF-8 From 49de139b8ea955ad5d4625b3de5d4c25a4b55e17 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 8 Apr 2024 13:42:28 +1000 Subject: [PATCH 0316/1116] Ip address format change --- scripts/aws/syslog-ng/syslog-ng-client.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 02d133ace..c3e3c888c 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -15,10 +15,10 @@ source s_syslog_udp { }; destination d_syslog_tcp { - syslog(ip("127.0.0.1") port(2011) transport("tcp")); + syslog("127.0.0.1" port(2011) transport("tcp")); }; destination d_syslog_udp { - syslog(ip("127.0.0.1") port(2010) transport("udp")); + syslog("127.0.0.1" port(2010) transport("udp")); }; destination d_file { From c6e5c804b5fef29a58a9084633acec9930847bb0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Apr 2024 03:43:28 +0000 Subject: [PATCH 0317/1116] [CI Pipeline] Released Snapshot version: 5.28.103-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2dd4ea9b4..8b5e16dd6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.101-SNAPSHOT + 5.28.103-SNAPSHOT UTF-8 From 47b4da430448f6bd192edf6bcdb7f55b378c13c8 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 8 Apr 2024 14:33:15 +1000 Subject: [PATCH 0318/1116] Added file source and dest --- scripts/aws/conf/logback.loki.xml | 12 ++++++++++++ scripts/aws/proxies.host.yaml | 4 ++-- scripts/aws/proxies.nitro.yaml | 4 ++-- scripts/aws/syslog-ng/syslog-ng-client.conf | 5 +++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/scripts/aws/conf/logback.loki.xml b/scripts/aws/conf/logback.loki.xml index bb2b27a9c..cbe4d179e 100644 --- a/scripts/aws/conf/logback.loki.xml +++ b/scripts/aws/conf/logback.loki.xml @@ -28,10 +28,22 @@ SYSLOG [%level] [%level] [%logger] [%thread] %msg %ex + + /var/log/uid2operator.log + true + + true + + + %-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n + + + \ No newline at end of file diff --git a/scripts/aws/proxies.host.yaml b/scripts/aws/proxies.host.yaml index deb691d5b..ceddc68d3 100644 --- a/scripts/aws/proxies.host.yaml +++ b/scripts/aws/proxies.host.yaml @@ -22,5 +22,5 @@ loki: syslogng: service: direct - listen: vsock://-1:2010 - connect: tcp://127.0.0.1:2010 \ No newline at end of file + listen: vsock://-1:2011 + connect: tcp://127.0.0.1:2011 \ No newline at end of file diff --git a/scripts/aws/proxies.nitro.yaml b/scripts/aws/proxies.nitro.yaml index d025b7c76..15fd4ab9a 100644 --- a/scripts/aws/proxies.nitro.yaml +++ b/scripts/aws/proxies.nitro.yaml @@ -27,5 +27,5 @@ loki: syslogng: service: direct - listen: tcp://0.0.0.0:2010 - connect: vsock://3:2010 \ No newline at end of file + listen: tcp://0.0.0.0:2011 + connect: vsock://3:2011 \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index c3e3c888c..3bccde791 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -21,6 +21,10 @@ destination d_syslog_udp { syslog("127.0.0.1" port(2010) transport("udp")); }; +source s_file { + file("/var/log/uid2operator.log"); +}; + destination d_file { file("/var/log/sysng.log"); }; @@ -28,5 +32,6 @@ destination d_file { log { source(s_local); source(s_syslog_udp); + source(s_file); destination(d_syslog_tcp); }; From 6323015f7b95eef2d88b9401cc8e249a33315556 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Apr 2024 04:34:03 +0000 Subject: [PATCH 0319/1116] [CI Pipeline] Released Snapshot version: 5.28.105-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b5e16dd6..afb9fd227 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.103-SNAPSHOT + 5.28.105-SNAPSHOT UTF-8 From 9f24846ede0b1298dd7e7b0661b61dc2913523be Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Apr 2024 11:44:48 -0600 Subject: [PATCH 0320/1116] generate with expired salts, shutdown after 12 hours --- src/main/java/com/uid2/operator/Main.java | 6 +- .../operator/service/UIDOperatorService.java | 12 +- .../vertx/OperatorShutdownHandler.java | 45 +++- .../operator/vertx/UIDOperatorVerticle.java | 8 +- .../operator/ExtendedUIDOperatorVerticle.java | 6 +- .../operator/OperatorShutdownHandlerTest.java | 97 +++++++- .../uid2/operator/UIDOperatorServiceTest.java | 13 +- .../operator/UIDOperatorVerticleTest.java | 230 +++++++++++++++++- .../operator/benchmark/BenchmarkCommon.java | 3 +- 9 files changed, 388 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index 5bbd874cd..a85b52c59 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -102,9 +102,9 @@ public Main(Vertx vertx, JsonObject config) throws Exception { DownloadCloudStorage fsStores; if (coreAttestUrl != null) { - this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Clock.systemUTC()); + this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC()); - var clients = createUidClients(this.vertx, coreAttestUrl, operatorKey, this.shutdownHandler::handleResponse); + var clients = createUidClients(this.vertx, coreAttestUrl, operatorKey, this.shutdownHandler::handleAttestResponse); UidCoreClient coreClient = clients.getKey(); UidOptOutClient optOutClient = clients.getValue(); fsStores = coreClient; @@ -251,7 +251,7 @@ private ICloudStorage wrapCloudStorageForOptOut(ICloudStorage cloudStorage) { private void run() throws Exception { Supplier operatorVerticleSupplier = () -> { - UIDOperatorVerticle verticle = new UIDOperatorVerticle(config, this.clientSideTokenGenerate, siteProvider, clientKeyProvider, clientSideKeypairProvider, getKeyManager(), saltProvider, optOutStore, Clock.systemUTC(), _statsCollectorQueue, new SecureLinkValidatorService(this.serviceLinkProvider, this.serviceProvider)); + UIDOperatorVerticle verticle = new UIDOperatorVerticle(config, this.clientSideTokenGenerate, siteProvider, clientKeyProvider, clientSideKeypairProvider, getKeyManager(), saltProvider, optOutStore, Clock.systemUTC(), _statsCollectorQueue, new SecureLinkValidatorService(this.serviceLinkProvider, this.serviceProvider), this.shutdownHandler::handleSaltRetrievalResponse); return verticle; }; diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 581e2970e..23a007b35 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -2,6 +2,7 @@ import com.uid2.operator.model.*; import com.uid2.operator.util.PrivacyBits; +import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.shared.model.SaltEntry; import com.uid2.operator.store.IOptOutStore; import com.uid2.shared.store.ISaltProvider; @@ -51,13 +52,16 @@ public class UIDOperatorService implements IUIDOperatorService { private final TokenVersion refreshTokenVersion; private final boolean identityV3Enabled; + private final Handler saltRetrievalResponseHandler; + public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProvider saltProvider, ITokenEncoder encoder, Clock clock, - IdentityScope identityScope) { + IdentityScope identityScope, Handler saltRetrievalResponseHandler) { this.saltProvider = saltProvider; this.encoder = encoder; this.optOutStore = optOutStore; this.clock = clock; this.identityScope = identityScope; + this.saltRetrievalResponseHandler = saltRetrievalResponseHandler; this.testOptOutIdentityForEmail = getFirstLevelHashIdentity(identityScope, IdentityType.Email, InputUtil.normalizeEmail(OptOutIdentityForEmail).getIdentityInput(), Instant.now()); @@ -207,8 +211,10 @@ public List getModifiedBuckets(Instant sinceTimestamp) { private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { ISaltProvider.ISaltSnapshot snapshot = this.saltProvider.getSnapshot(asOf); - if(snapshot == null) { - LOGGER.error("SaltProvider returned NULL on getSnapshot for instant {}", asOf); + if(snapshot.getExpires().isBefore(Instant.now())) { + saltRetrievalResponseHandler.handle(true); + } else { + saltRetrievalResponseHandler.handle(false); } return snapshot; } diff --git a/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java b/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java index 9c41ec184..d4240aef5 100644 --- a/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java +++ b/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java @@ -7,32 +7,59 @@ import java.time.Clock; import java.time.Duration; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.concurrent.atomic.AtomicReference; public class OperatorShutdownHandler { private static final Logger LOGGER = LoggerFactory.getLogger(OperatorShutdownHandler.class); - private final Duration shutdownWaitTime; - private final AtomicReference failureStartTime = new AtomicReference<>(null); + private final Duration attestShutdownWaitTime; + private final Duration saltShutdownWaitTime; + private final AtomicReference attestFailureStartTime = new AtomicReference<>(null); + private final AtomicReference saltFailureStartTime = new AtomicReference<>(null); + private final AtomicReference lastSaltFailureLogTime = new AtomicReference<>(null); private final Clock clock; - public OperatorShutdownHandler(Duration shutdownWaitTime, Clock clock) { - this.shutdownWaitTime = shutdownWaitTime; + public OperatorShutdownHandler(Duration attestShutdownWaitTime, Duration saltShutdownWaitTime, Clock clock) { + this.attestShutdownWaitTime = attestShutdownWaitTime; + this.saltShutdownWaitTime = saltShutdownWaitTime; this.clock = clock; } + public void handleSaltRetrievalResponse(Boolean expired) { + if(!expired) { + saltFailureStartTime.set(null); + } else { + logSaltFailureAtInterval(); + Instant t = saltFailureStartTime.get(); + if (t == null) { + saltFailureStartTime.set(clock.instant()); + } else if(Duration.between(t, clock.instant()).compareTo(this.saltShutdownWaitTime) > 0) { + LOGGER.error("salts have been in expired state for too long. shutting down operator"); + System.exit(1); + } + } + } + + public void logSaltFailureAtInterval() { + Instant t = lastSaltFailureLogTime.get(); + if(t == null || clock.instant().isAfter(t.plus(10, ChronoUnit.MINUTES))) { + LOGGER.error("all salts are expired"); + lastSaltFailureLogTime.set(Instant.now()); + } + } - public void handleResponse(Pair response) { + public void handleAttestResponse(Pair response) { if (response.left() == 401) { LOGGER.error("core attestation failed with 401, shutting down operator, core response: " + response.right()); System.exit(1); } if (response.left() == 200) { - failureStartTime.set(null); + attestFailureStartTime.set(null); } else { - Instant t = failureStartTime.get(); + Instant t = attestFailureStartTime.get(); if (t == null) { - failureStartTime.set(clock.instant()); - } else if (Duration.between(t, clock.instant()).compareTo(this.shutdownWaitTime) > 0) { + attestFailureStartTime.set(clock.instant()); + } else if (Duration.between(t, clock.instant()).compareTo(this.attestShutdownWaitTime) > 0) { LOGGER.error("core attestation has been in failed state for too long. shutting down operator"); System.exit(1); } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index e9c59af56..ac1d7c087 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -110,6 +110,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final boolean clientSideTokenGenerateLogInvalidHttpOrigin; public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); + private final Handler saltRetrievalResponseHandler; private final int maxBidstreamLifetimeSeconds; private final int allowClockSkewSeconds; @@ -128,7 +129,8 @@ public UIDOperatorVerticle(JsonObject config, IOptOutStore optOutStore, Clock clock, IStatsCollectorQueue statsCollectorQueue, - SecureLinkValidatorService secureLinkValidatorService) { + SecureLinkValidatorService secureLinkValidatorService, + Handler saltRetrievalResponseHandler) { this.keyManager = keyManager; this.secureLinkValidatorService = secureLinkValidatorService; try { @@ -163,6 +165,7 @@ public UIDOperatorVerticle(JsonObject config, } this.allowClockSkewSeconds = config.getInteger(Const.Config.AllowClockSkewSecondsProp, 1800); this.maxSharingLifetimeSeconds = config.getInteger(Const.Config.MaxSharingLifetimeProp, config.getInteger(Const.Config.SharingTokenExpiryProp)); + this.saltRetrievalResponseHandler = saltRetrievalResponseHandler; } @Override @@ -174,7 +177,8 @@ public void start(Promise startPromise) throws Exception { this.saltProvider, this.encoder, this.clock, - this.identityScope + this.identityScope, + this.saltRetrievalResponseHandler ); final Router router = createRoutesSetup(); diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index 1793f6016..e3db51518 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -7,6 +7,7 @@ import com.uid2.operator.store.IOptOutStore; import com.uid2.operator.vertx.UIDOperatorVerticle; import com.uid2.shared.store.*; +import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import java.time.Clock; @@ -26,8 +27,9 @@ public ExtendedUIDOperatorVerticle(JsonObject config, IOptOutStore optOutStore, Clock clock, IStatsCollectorQueue statsCollectorQueue, - SecureLinkValidatorService secureLinkValidationService) { - super(config, clientSideTokenGenerate, siteProvider, clientKeyProvider, clientSideKeypairProvider, keyManager, saltProvider, optOutStore, clock, statsCollectorQueue, secureLinkValidationService); + SecureLinkValidatorService secureLinkValidationService, + Handler saltRetrievalResponseHandler) { + super(config, clientSideTokenGenerate, siteProvider, clientKeyProvider, clientSideKeypairProvider, keyManager, saltProvider, optOutStore, clock, statsCollectorQueue, secureLinkValidationService, saltRetrievalResponseHandler); } public IUIDOperatorService getIdService() { diff --git a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java index dc71116df..8ca40fe6d 100644 --- a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java +++ b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java @@ -48,7 +48,7 @@ public void checkExit(int status) { void beforeEach() { mocks = MockitoAnnotations.openMocks(this); when(clock.instant()).thenAnswer(i -> Instant.now()); - this.operatorShutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), clock); + this.operatorShutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), clock); } @AfterEach @@ -57,7 +57,7 @@ void afterEach() throws Exception { } @Test - void shutdownOn401(Vertx vertx, VertxTestContext testContext) { + void shutdownOnAttest401(Vertx vertx, VertxTestContext testContext) { SecurityManager origSecurityManager = System.getSecurityManager(); try { System.setSecurityManager(new NoExitSecurityManager()); @@ -68,7 +68,7 @@ void shutdownOn401(Vertx vertx, VertxTestContext testContext) { // Revoke auth try { - this.operatorShutdownHandler.handleResponse(Pair.of(401, "Unauthorized")); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(401, "Unauthorized")); } catch (RuntimeException e) { Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("core attestation failed with 401, shutting down operator, core response: ")); testContext.completeNow(); @@ -79,7 +79,7 @@ void shutdownOn401(Vertx vertx, VertxTestContext testContext) { } @Test - void shutdownOnFailedTooLong(Vertx vertx, VertxTestContext testContext) { + void shutdownOnAttestFailedTooLong(Vertx vertx, VertxTestContext testContext) { SecurityManager origSecurityManager = System.getSecurityManager(); try { System.setSecurityManager(new NoExitSecurityManager()); @@ -88,11 +88,11 @@ void shutdownOnFailedTooLong(Vertx vertx, VertxTestContext testContext) { logWatcher.start(); ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - this.operatorShutdownHandler.handleResponse(Pair.of(500, "")); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); try { - this.operatorShutdownHandler.handleResponse(Pair.of(500, "")); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); } catch (RuntimeException e) { Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("core attestation has been in failed state for too long. shutting down operator")); testContext.completeNow(); @@ -112,17 +112,96 @@ void attestRecoverOnSuccess(Vertx vertx, VertxTestContext testContext) { logWatcher.start(); ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - this.operatorShutdownHandler.handleResponse(Pair.of(500, "")); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); - this.operatorShutdownHandler.handleResponse(Pair.of(200, "")); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(200, "")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); assertDoesNotThrow(() -> { - this.operatorShutdownHandler.handleResponse(Pair.of(500, "")); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); }); testContext.completeNow(); } finally { System.setSecurityManager(origSecurityManager); } } + + @Test + void shutdownOnSaltsExpiredTooLong(Vertx vertx, VertxTestContext testContext) { + SecurityManager origSecurityManager = System.getSecurityManager(); + try { + System.setSecurityManager(new NoExitSecurityManager()); + + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + + when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); + try { + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + } catch (RuntimeException e) { + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); + Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator")); + testContext.completeNow(); + } + } finally { + System.setSecurityManager(origSecurityManager); + } + } + + @Test + void saltsRecoverOnSuccess(Vertx vertx, VertxTestContext testContext) { + SecurityManager origSecurityManager = System.getSecurityManager(); + try { + System.setSecurityManager(new NoExitSecurityManager()); + + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); + this.operatorShutdownHandler.handleSaltRetrievalResponse(false); + + when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); + assertDoesNotThrow(() -> { + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + }); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); + testContext.completeNow(); + } finally { + System.setSecurityManager(origSecurityManager); + } + } + + @Test + void saltsLogErrorAtInterval(Vertx vertx, VertxTestContext testContext) { + SecurityManager origSecurityManager = System.getSecurityManager(); + try { + System.setSecurityManager(new NoExitSecurityManager()); + + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(9, ChronoUnit.MINUTES)); + Assertions.assertEquals(1, logWatcher.list.size()); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(11, ChronoUnit.MINUTES)); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); + Assertions.assertEquals(2, logWatcher.list.size()); + + testContext.completeNow(); + } finally { + System.setSecurityManager(origSecurityManager); + } + } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 9e52c3692..af2cd0ce2 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -6,6 +6,7 @@ import com.uid2.operator.service.InputUtil; import com.uid2.operator.service.UIDOperatorService; import com.uid2.operator.store.IOptOutStore; +import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.shared.store.CloudPath; import com.uid2.shared.store.RotatingSaltProvider; import com.uid2.shared.cloud.EmbeddedResourceStorage; @@ -27,6 +28,7 @@ import java.nio.charset.StandardCharsets; import java.security.Security; import java.time.Clock; +import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -37,6 +39,7 @@ public class UIDOperatorServiceTest { private AutoCloseable mocks; @Mock private IOptOutStore optOutStore; @Mock private Clock clock; + @Mock private OperatorShutdownHandler shutdownHandler; EncryptedTokenEncoder tokenEncoder; UIDOperatorService uid2Service; UIDOperatorService euidService; @@ -79,13 +82,16 @@ void setup() throws Exception { uid2Config.put("advertising_token_v3", false); // prod is using v2 token version for now uid2Config.put("identity_v3", false); + this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC()); + uid2Service = new UIDOperatorService( uid2Config, optOutStore, saltProvider, tokenEncoder, this.clock, - IdentityScope.UID2 + IdentityScope.UID2, + this.shutdownHandler::handleSaltRetrievalResponse ); final JsonObject euidConfig = new JsonObject(); @@ -96,13 +102,16 @@ void setup() throws Exception { euidConfig.put("advertising_token_v3", true); euidConfig.put("identity_v3", true); + this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC()); + euidService = new UIDOperatorService( euidConfig, optOutStore, saltProvider, tokenEncoder, this.clock, - IdentityScope.EUID + IdentityScope.EUID, + this.shutdownHandler::handleSaltRetrievalResponse ); } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 5bbb03bfa..60451ade3 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -11,6 +11,7 @@ import com.uid2.operator.store.IOptOutStore; import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.util.Tuple; +import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.operator.vertx.UIDOperatorVerticle; import com.uid2.operator.vertx.ClientInputValidationException; import com.uid2.shared.Utils; @@ -107,6 +108,7 @@ public class UIDOperatorVerticleTest { @Mock private IOptOutStore optOutStore; @Mock private Clock clock; @Mock private IStatsCollectorQueue statsCollectorQueue; + @Mock private OperatorShutdownHandler shutdownHandler; private SimpleMeterRegistry registry; private ExtendedUIDOperatorVerticle uidOperatorVerticle; @@ -116,6 +118,7 @@ public class UIDOperatorVerticleTest { public void deployVerticle(Vertx vertx, VertxTestContext testContext, TestInfo testInfo) { mocks = MockitoAnnotations.openMocks(this); when(saltProvider.getSnapshot(any())).thenReturn(saltProviderSnapshot); + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().plus(1, ChronoUnit.HOURS)); when(clock.instant()).thenAnswer(i -> now); when(this.secureLinkValidatorService.validateRequest(any(RoutingContext.class), any(JsonObject.class), any(Role.class))).thenReturn(true); @@ -124,7 +127,7 @@ public void deployVerticle(Vertx vertx, VertxTestContext testContext, TestInfo t config.put("enable_phone_support", false); } - this.uidOperatorVerticle = new ExtendedUIDOperatorVerticle(config, config.getBoolean("client_side_token_generate"), siteProvider, clientKeyProvider, clientSideKeypairProvider, new KeyManager(keysetKeyStore, keysetProvider), saltProvider, optOutStore, clock, statsCollectorQueue, secureLinkValidatorService); + this.uidOperatorVerticle = new ExtendedUIDOperatorVerticle(config, config.getBoolean("client_side_token_generate"), siteProvider, clientKeyProvider, clientSideKeypairProvider, new KeyManager(keysetKeyStore, keysetProvider), saltProvider, optOutStore, clock, statsCollectorQueue, secureLinkValidatorService, shutdownHandler::handleSaltRetrievalResponse); vertx.deployVerticle(uidOperatorVerticle, testContext.succeeding(id -> testContext.completeNow())); @@ -1286,6 +1289,65 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t }); } + @ParameterizedTest + @ValueSource(strings = {"v1", "v2"}) + void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext testContext) { + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); + final int clientSiteId = 201; + final String emailAddress = "test@uid2.com"; + fakeAuth(clientSiteId, Role.GENERATOR); + setupSalts(); + setupKeys(); + + generateTokens(apiVersion, vertx, "email", emailAddress, genRespJson -> { + assertEquals("success", genRespJson.getString("status")); + JsonObject bodyJson = genRespJson.getJsonObject("body"); + assertNotNull(bodyJson); + + String genRefreshToken = bodyJson.getString("refresh_token"); + + when(this.optOutStore.getLatestEntry(any())).thenReturn(null); + + sendTokenRefresh(apiVersion, vertx, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> + { + assertEquals("success", refreshRespJson.getString("status")); + JsonObject refreshBody = refreshRespJson.getJsonObject("body"); + assertNotNull(refreshBody); + EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + + AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + + assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + + String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); + assertNotEquals(genRefreshToken, refreshTokenStringNew); + RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew); + assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + + assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); + assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); + assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_from")), 10); + + assertTokenStatusMetrics( + clientSiteId, + apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.GenerateV1 : TokenResponseStatsCollector.Endpoint.GenerateV2, + TokenResponseStatsCollector.ResponseStatus.Success); + assertTokenStatusMetrics( + clientSiteId, + apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, + TokenResponseStatsCollector.ResponseStatus.Success); + + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + + testContext.completeNow(); + }); + }); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateThenValidateWithEmail_Match(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -1410,6 +1472,51 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo }); } + @ParameterizedTest + @ValueSource(strings = {"v1", "v2"}) + void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext testContext) { + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); + final int clientSiteId = 201; + final String emailAddress = "test@uid2.com"; + fakeAuth(clientSiteId, Role.GENERATOR); + setupSalts(); + setupKeys(); + + String v1Param = "email=" + emailAddress; + JsonObject v2Payload = new JsonObject(); + v2Payload.put("email", emailAddress); + + sendTokenGenerate(apiVersion, vertx, + v1Param, v2Payload, 200, + json -> { + assertEquals("success", json.getString("status")); + JsonObject body = json.getJsonObject("body"); + assertNotNull(body); + EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + + AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); + + assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + + RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + + assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); + assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); + assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_from")), 10); + + assertStatsCollector("/" + apiVersion + "/token/generate", null, "test-contact", clientSiteId); + + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + + testContext.completeNow(); + }); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenRefreshNoToken(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -1734,6 +1841,33 @@ void identityMapForEmail(Vertx vertx, VertxTestContext testContext) { }); } + @Test + void identityMapForSaltsExpired(Vertx vertx, VertxTestContext testContext) { + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); + final int clientSiteId = 201; + final String emailAddress = "test@uid2.com"; + fakeAuth(clientSiteId, Role.MAPPER); + setupSalts(); + setupKeys(); + get(vertx, "v1/identity/map?email=" + emailAddress, ar -> { + assertTrue(ar.succeeded()); + HttpResponse response = ar.result(); + assertEquals(200, response.statusCode()); + JsonObject json = response.bodyAsJsonObject(); + assertEquals("success", json.getString("status")); + JsonObject body = json.getJsonObject("body"); + assertNotNull(body); + + assertEquals(emailAddress, body.getString("identifier")); + assertFalse(body.getString("advertising_id").isEmpty()); + assertFalse(body.getString("bucket_id").isEmpty()); + + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + + testContext.completeNow(); + }); + } + @Test void identityMapForEmailHash(Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; @@ -1945,6 +2079,33 @@ void LogoutV2(Vertx vertx, VertxTestContext testContext) { }); } + @Test + void LogoutV2SaltsExpired(Vertx vertx, VertxTestContext testContext) { + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); + final int clientSiteId = 201; + fakeAuth(clientSiteId, Role.OPTOUT); + setupSalts(); + setupKeys(); + + JsonObject req = new JsonObject(); + req.put("email", "test@uid2.com"); + + doAnswer(invocation -> { + Handler> handler = invocation.getArgument(2); + handler.handle(Future.succeededFuture(Instant.now())); + return null; + }).when(this.optOutStore).addEntry(any(), any(), any()); + + send("v2", vertx, "v2/token/logout", false, null, req, 200, respJson -> { + assertEquals("success", respJson.getString("status")); + assertEquals("OK", respJson.getJsonObject("body").getString("optout")); + + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + + testContext.completeNow(); + }); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateBothPhoneAndHashSpecified(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -2170,6 +2331,39 @@ void tokenGenerateThenValidateWithPhone_Match(String apiVersion, Vertx vertx, Ve }); } + @ParameterizedTest + @ValueSource(strings = {"v1", "v2"}) + void tokenGenerateThenValidateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext testContext) { + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); + final int clientSiteId = 201; + final String phone = ValidateIdentityForPhone; + fakeAuth(clientSiteId, Role.GENERATOR); + setupSalts(); + setupKeys(); + + generateTokens(apiVersion, vertx, "phone", phone, genRespJson -> { + assertEquals("success", genRespJson.getString("status")); + JsonObject genBody = genRespJson.getJsonObject("body"); + assertNotNull(genBody); + + String advertisingTokenString = genBody.getString("advertising_token"); + + String v1Param = "token=" + urlEncode(advertisingTokenString) + "&phone=" + urlEncode(phone); + JsonObject v2Payload = new JsonObject(); + v2Payload.put("token", advertisingTokenString); + v2Payload.put("phone", phone); + + send(apiVersion, vertx, apiVersion + "/token/validate", true, v1Param, v2Payload, 200, json -> { + assertTrue(json.getBoolean("body")); + assertEquals("success", json.getString("status")); + + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + + testContext.completeNow(); + }); + }); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateThenValidateWithPhoneHash_Match(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -3529,6 +3723,40 @@ else if(identityType == IdentityType.Phone) { }); } + @ParameterizedTest + @CsvSource({ + "true,https://cstg.co.uk", + "false,https://cstg.co.uk", + "true,https://cstg2.com", + "false,https://cstg2.com", + "true,http://localhost:8080", + "false,http://localhost:8080", + }) + void cstgSaltsExpired(boolean setOptoutCheckFlagInRequest, String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); + setupCstgBackend("cstg.co.uk", "cstg2.com", "localhost"); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), setOptoutCheckFlagInRequest); + sendCstg(vertx, + "v2/token/client-generate", + httpOrigin, + data.getItem1(), + data.getItem2(), + 200, + testContext, + respJson -> { + assertEquals("success", respJson.getString("status")); + + JsonObject refreshBody = respJson.getJsonObject("body"); + assertNotNull(refreshBody); + var encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + validateAndGetToken(encoder, refreshBody, IdentityType.Email); //to validate token version is correct + + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + + testContext.completeNow(); + }); + } + private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectClientSideTokenGenerateOptoutResponse) { assertAreClientSideGeneratedTokens(advertisingToken, diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 9e29dadaa..38f870c6b 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -81,7 +81,8 @@ static IUIDOperatorService createUidOperatorService() throws Exception { saltProvider, tokenEncoder, Clock.systemUTC(), - IdentityScope.UID2 + IdentityScope.UID2, + null ); } From abe37be696d41ab2da0d50d7822f91e7464e7c3d Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Apr 2024 11:48:21 -0600 Subject: [PATCH 0321/1116] remove redundant check from test --- src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java index 8ca40fe6d..d575be5c5 100644 --- a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java +++ b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java @@ -195,7 +195,6 @@ void saltsLogErrorAtInterval(Vertx vertx, VertxTestContext testContext) { Assertions.assertEquals(1, logWatcher.list.size()); when(clock.instant()).thenAnswer(i -> Instant.now().plus(11, ChronoUnit.MINUTES)); this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); Assertions.assertEquals(2, logWatcher.list.size()); From 058720d7d8d9319e2409bfd75cae403dfc401780 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Apr 2024 14:09:42 -0600 Subject: [PATCH 0322/1116] no active encryption key error handling --- src/main/java/com/uid2/operator/Main.java | 12 +++ .../com/uid2/operator/model/KeyManager.java | 15 +++- .../uid2/operator/model/RefreshResponse.java | 8 +- .../TokenResponseStatsCollector.java | 3 +- .../operator/service/UIDOperatorService.java | 2 + .../operator/vertx/GenericFailureHandler.java | 1 + .../operator/vertx/UIDOperatorVerticle.java | 23 ++++-- .../operator/UIDOperatorVerticleTest.java | 79 ++++++++++++++++++- 8 files changed, 130 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index a85b52c59..12dc3874b 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -50,6 +50,7 @@ import java.nio.file.Paths; import java.time.Clock; import java.time.Duration; +import java.time.Instant; import java.util.*; import java.util.function.Supplier; @@ -164,6 +165,17 @@ public Main(Vertx vertx, JsonObject config) throws Exception { this.serviceProvider.loadContent(); this.serviceLinkProvider.loadContent(); } + + try { + getKeyManager().getMasterKey(); + } catch (KeyManager.NoActiveKeyException e) { + LOGGER.error("No active master key found", e); + System.exit(1); + } + if(saltProvider.getSnapshot(Instant.now()).getExpires().isBefore(Instant.now())) { + LOGGER.error("All salts are expired"); + System.exit(1); + } } metrics = new OperatorMetrics(getKeyManager(), saltProvider); } diff --git a/src/main/java/com/uid2/operator/model/KeyManager.java b/src/main/java/com/uid2/operator/model/KeyManager.java index 10e1f0904..3df37798d 100644 --- a/src/main/java/com/uid2/operator/model/KeyManager.java +++ b/src/main/java/com/uid2/operator/model/KeyManager.java @@ -5,12 +5,14 @@ import com.uid2.shared.auth.Keyset; import com.uid2.shared.model.KeysetKey; import com.uid2.shared.store.IKeysetKeyStore; +import com.uid2.shared.store.KeysetKeyStoreSnapshot; import com.uid2.shared.store.reader.RotatingKeysetProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.time.Instant; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -38,7 +40,7 @@ public KeysetKey getActiveKeyBySiteIdWithFallback(int siteId, int fallbackSiteId KeysetKey key = getActiveKeyBySiteId(siteId, asOf); if (key == null) key = getActiveKeyBySiteId(fallbackSiteId, asOf); if (key == null) { - throw new IllegalArgumentException(String.format("Cannot get active key in default keyset with SITE ID %d or %d.", siteId, fallbackSiteId)); + throw new NoActiveKeyException(String.format("Cannot get active key in default keyset with SITE ID %d or %d.", siteId, fallbackSiteId)); } return key; } @@ -103,10 +105,11 @@ public Map getAllKeysets() { public KeysetKey getMasterKey() { return getMasterKey(Instant.now()); } + KeysetKeyStoreSnapshot keysetKeyStoreSnapshot = new KeysetKeyStoreSnapshot(new HashMap<>(), new HashMap<>()); public KeysetKey getMasterKey(Instant asOf) { KeysetKey key = this.keysetKeyStore.getSnapshot().getActiveKey(Const.Data.MasterKeysetId, asOf); if (key == null) { - throw new RuntimeException(String.format("Cannot get a master key with keyset ID %d.", Const.Data.MasterKeysetId)); + throw new NoActiveKeyException(String.format("Cannot get a master key with keyset ID %d.", Const.Data.MasterKeysetId)); } return key; } @@ -118,8 +121,14 @@ public KeysetKey getRefreshKey() { public KeysetKey getRefreshKey(Instant asOf) { KeysetKey key = this.keysetKeyStore.getSnapshot().getActiveKey(Const.Data.RefreshKeysetId, asOf); if (key == null) { - throw new RuntimeException(String.format("Cannot get a refresh key with keyset ID %d.", Const.Data.RefreshKeysetId)); + throw new NoActiveKeyException(String.format("Cannot get a refresh key with keyset ID %d.", Const.Data.RefreshKeysetId)); } return key; } + + public class NoActiveKeyException extends RuntimeException { + NoActiveKeyException(String message) { + super(message); + } + } } diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index 7671271ed..fbe41f96b 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -8,6 +8,7 @@ public class RefreshResponse { public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityTokens.LogoutToken); public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityTokens.LogoutToken); public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityTokens.LogoutToken); + public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityTokens.LogoutToken); private final Status status; private final IdentityTokens tokens; private final Duration durationSinceLastRefresh; @@ -62,12 +63,17 @@ public boolean isExpired() { return Status.Expired.equals(this.status); } + public boolean noActiveKey() { + return Status.NoActiveKey.equals(this.status); + } + public enum Status { Refreshed, Invalid, Optout, Expired, - Deprecated + Deprecated, + NoActiveKey } } diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index b565786f9..00037186b 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -36,7 +36,8 @@ public enum ResponseStatus { BadJsonPayload, // can't even deserialise the JSON payload PayloadHasNoBody, /* End of CSTG-related Status */ - Unknown + Unknown, + NoActiveKey } public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus) { diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 23a007b35..642b3d130 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -163,6 +163,8 @@ public RefreshResponse refreshIdentity(RefreshToken token) { } else { return RefreshResponse.Optout; } + } catch (KeyManager.NoActiveKeyException e) { + return RefreshResponse.NoActiveKey; } catch (Exception ex) { return RefreshResponse.Invalid; } diff --git a/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java b/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java index 855ea1187..905013821 100644 --- a/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java +++ b/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java @@ -1,5 +1,6 @@ package com.uid2.operator.vertx; +import com.uid2.operator.model.KeyManager; import io.vertx.core.Handler; import io.vertx.core.http.HttpClosedException; import io.vertx.core.http.HttpServerResponse; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index ac1d7c087..5a6c75360 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -436,12 +436,17 @@ else if(emailHash != null) { privacyBits.setClientSideTokenGenerateOptoutResponse(); } - IdentityTokens identityTokens = this.idService.generateIdentity( - new IdentityRequest( - new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), - input.toUserIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), - OptoutCheckPolicy.RespectOptOut)); - + IdentityTokens identityTokens; + try { + identityTokens = this.idService.generateIdentity( + new IdentityRequest( + new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), + input.toUserIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), + OptoutCheckPolicy.RespectOptOut)); + } catch (KeyManager.NoActiveKeyException e){ + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e); + return; + } JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; @@ -769,6 +774,8 @@ private void handleTokenRefreshV2(RoutingContext rc) { ResponseUtil.Warning(ResponseStatus.InvalidToken, 400, rc, "Invalid Token presented"); } else if (r.isExpired()) { ResponseUtil.Warning(ResponseStatus.ExpiredToken, 400, rc, "Expired Token presented"); + } else if (r.noActiveKey()) { + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new Exception("No active encryption key available")); } else { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } @@ -910,7 +917,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { OptoutCheckPolicy.respectOptOut())); if (t.isEmptyToken()) { - if(optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy + if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) : InputUtil.InputVal.validPhone(OptOutTokenIdentityForPhone, OptOutTokenIdentityForPhone); @@ -936,6 +943,8 @@ private void handleTokenGenerateV2(RoutingContext rc) { recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion()); } } + } catch (KeyManager.NoActiveKeyException e) { + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e); } catch (ClientInputValidationException cie) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "request body contains invalid argument(s)", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider); } catch (Exception e) { diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 60451ade3..f68494ead 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -516,7 +516,14 @@ private void setupKeysetsKeysMock(HashMap> keysetIdToKe } protected void setupKeys() { - final Instant expiryTime = now.plus(25, ChronoUnit.HOURS); //Some tests move the clock forward to test token expiry, so ensure these keys expire after that time. + setupKeys(false); + } + + protected void setupKeys(boolean expired) { + Instant expiryTime = now.plus(25, ChronoUnit.HOURS); //Some tests move the clock forward to test token expiry, so ensure these keys expire after that time. + if(expired) { + expiryTime = now.minus(25, ChronoUnit.HOURS); //Some tests move the clock forward to test token expiry, so ensure these keys expire after that time. + } KeysetKey masterKey = new KeysetKey(101, makeAesKey("masterKey"), now.minusSeconds(7), now, expiryTime, MasterKeysetId); KeysetKey refreshKey = new KeysetKey(102, makeAesKey("refreshKey"), now.minusSeconds(7), now, expiryTime, RefreshKeysetId); KeysetKey publisherKey = new KeysetKey(103, makeAesKey("publisherKey"), now.minusSeconds(7), now, expiryTime, FallbackPublisherKeysetId); @@ -1348,6 +1355,37 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT }); } + @Test + void tokenGenerateThenRefreshNoActiveKey(Vertx vertx, VertxTestContext testContext) { + final int clientSiteId = 201; + fakeAuth(clientSiteId, newClientCreationDateTime, Role.GENERATOR); + setupSalts(); + setupKeys(); + + JsonObject v2Payload = new JsonObject(); + v2Payload.put("email", "test@email.com"); + v2Payload.put("optout_check", 1); + + sendTokenGenerate("v2", vertx, + "", v2Payload, 200, + genRespJson -> { + assertEquals("success", genRespJson.getString("status")); + JsonObject bodyJson = genRespJson.getJsonObject("body"); + assertNotNull(bodyJson); + + String genRefreshToken = bodyJson.getString("refresh_token"); + + setupKeys(true); + sendTokenRefresh("v2", vertx, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 500, refreshRespJson -> + { + assertFalse(refreshRespJson.containsKey("body")); + assertEquals("No active encryption key available", refreshRespJson.getString("message")); + testContext.completeNow(); + }); + }); + } + + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateThenValidateWithEmail_Match(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -1517,6 +1555,26 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext }); } + @Test + void tokenGenerateNoActiveKey(Vertx vertx, VertxTestContext testContext) { + final int clientSiteId = 201; + fakeAuth(clientSiteId, newClientCreationDateTime, Role.GENERATOR); + setupSalts(); + setupKeys(true); + + JsonObject v2Payload = new JsonObject(); + v2Payload.put("email", "test@email.com"); + v2Payload.put("optout_check", 1); + + sendTokenGenerate("v2", vertx, + "", v2Payload, 500, + json -> { + assertFalse(json.containsKey("body")); + assertEquals("No active encryption key available", json.getString("message")); + testContext.completeNow(); + }); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenRefreshNoToken(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -3757,6 +3815,25 @@ void cstgSaltsExpired(boolean setOptoutCheckFlagInRequest, String httpOrigin, Ve }); } + @Test + void cstgNoActiveKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + setupCstgBackend("cstg.co.uk"); + setupKeys(true); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), true); + sendCstg(vertx, + "v2/token/client-generate", + "http://cstg.co.uk", + data.getItem1(), + data.getItem2(), + 500, + testContext, + respJson -> { + assertFalse(respJson.containsKey("body")); + assertEquals("No active encryption key available", respJson.getString("message")); + testContext.completeNow(); + }); + } + private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectClientSideTokenGenerateOptoutResponse) { assertAreClientSideGeneratedTokens(advertisingToken, From bf9dcbb496afcd91ad54c8346474f1b082fceffc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 9 Apr 2024 12:47:47 +1000 Subject: [PATCH 0323/1116] Testing reducing the range of addresses for vsock proxy --- scripts/aws/proxies.host.yaml | 6 +++--- scripts/aws/proxies.nitro.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/aws/proxies.host.yaml b/scripts/aws/proxies.host.yaml index ceddc68d3..7069a6fde 100644 --- a/scripts/aws/proxies.host.yaml +++ b/scripts/aws/proxies.host.yaml @@ -2,7 +2,7 @@ socks5h-proxy: service: direct - listen: vsock://-1:3305 + listen: vsock://42:3305 connect: tcp://127.0.0.1:3306 operator-service: @@ -17,10 +17,10 @@ operator-prometheus: loki: service: direct - listen: vsock://-1:3100 + listen: vsock://42:3100 connect: tcp://127.0.0.1:3100 syslogng: service: direct - listen: vsock://-1:2011 + listen: vsock://42:2011 connect: tcp://127.0.0.1:2011 \ No newline at end of file diff --git a/scripts/aws/proxies.nitro.yaml b/scripts/aws/proxies.nitro.yaml index 15fd4ab9a..9772f3bb1 100644 --- a/scripts/aws/proxies.nitro.yaml +++ b/scripts/aws/proxies.nitro.yaml @@ -12,7 +12,7 @@ prometheus-server: socks5h-proxy: service: direct - listen: tcp://0.0.0.0:3305 + listen: tcp://127.0.0.1:3305 connect: vsock://3:3305 aws-service-proxy: @@ -22,10 +22,10 @@ aws-service-proxy: loki: service: direct - listen: tcp://0.0.0.0:3100 + listen: tcp://127.0.0.1:3100 connect: vsock://3:3100 syslogng: service: direct - listen: tcp://0.0.0.0:2011 + listen: tcp://127.0.0.1:2011 connect: vsock://3:2011 \ No newline at end of file From e90622848ed09fd2970d9e2dd90b4266020475d0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Apr 2024 02:48:50 +0000 Subject: [PATCH 0324/1116] [CI Pipeline] Released Snapshot version: 5.28.107-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index afb9fd227..f37fa45ee 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.105-SNAPSHOT + 5.28.107-SNAPSHOT UTF-8 From 5463c9384345f0b5c2b9f74f97dea4c2f91eae9d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 10 Apr 2024 09:22:18 +1000 Subject: [PATCH 0325/1116] Change port --- scripts/aws/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 460071609..775970edf 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -35,7 +35,7 @@ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf -EXPOSE 2010 +EXPOSE 2011 RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh From 9d9499e10cc5f52be791004d707eac9e5125a6cc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 10 Apr 2024 09:24:35 +1000 Subject: [PATCH 0326/1116] Moved source file for syslog-ng --- scripts/aws/syslog-ng/syslog-ng-client.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 3bccde791..c173dfae3 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -14,6 +14,10 @@ source s_syslog_udp { ); }; +source s_file { + file("/var/log/uid2operator.log"); +}; + destination d_syslog_tcp { syslog("127.0.0.1" port(2011) transport("tcp")); }; @@ -21,10 +25,6 @@ destination d_syslog_udp { syslog("127.0.0.1" port(2010) transport("udp")); }; -source s_file { - file("/var/log/uid2operator.log"); -}; - destination d_file { file("/var/log/sysng.log"); }; From f0b55ad6e99e5ed90b194114b0a52645532d7697 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 10 Apr 2024 11:07:31 +1000 Subject: [PATCH 0327/1116] Revert "Separate UID2 and EUID EIF build steps (#453)" (#480) This reverts commit 922578729e25b7923f67b4bf24d97f4f4c081a7d. --- .../publish-aws-nitro-enclave-docker.yaml | 115 +++--------------- 1 file changed, 19 insertions(+), 96 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 9998c6e6a..cbd9e559c 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -31,8 +31,8 @@ env: ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts jobs: - start: - name: Start Building AWS Image + buildImage: + name: Build Image runs-on: ubuntu-latest steps: - name: Check branch and release type @@ -112,37 +112,6 @@ jobs: add: 'pom.xml version.json' message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} - outputs: - new_version: ${{ steps.version.outputs.new_version }} - is_release: ${{ steps.checkRelease.outputs.is_release }} - github_changelog: ${{ steps.github_release.outputs.changelog }} - - buildUID2EIF: - name: Build UID2 EIF - runs-on: ubuntu-latest - needs: start - steps: - - name: Checkout full history on Main - uses: actions/checkout@v4 - if: ${{ inputs.version_number_input == '' }} - with: - # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. - fetch-depth: 0 - - - name: Checkout full history at tag v${{ inputs.version_number_input }} - uses: actions/checkout@v4 - if: ${{ inputs.version_number_input != '' }} - with: - ref: v${{ inputs.version_number_input }} - # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. - fetch-depth: 0 - - - name: Restore timestamps - uses: thetradedesk/git-restore-mtime-action@v1.3 - - - name: Free up space - delete preinstalled tools - run: | - rm -rf /opt/hostedtoolcache - name: Build UID2 AWS EIF id: build_uid2_eif @@ -154,39 +123,10 @@ jobs: - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: - name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} + name: aws-uid2-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error - outputs: - uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} - - buildEUIDEIF: - name: Build EUID EIF - runs-on: ubuntu-latest - needs: start - steps: - - name: Checkout full history on Main - uses: actions/checkout@v4 - if: ${{ inputs.version_number_input == '' }} - with: - # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. - fetch-depth: 0 - - - name: Checkout full history at tag v${{ inputs.version_number_input }} - uses: actions/checkout@v4 - if: ${{ inputs.version_number_input != '' }} - with: - ref: v${{ inputs.version_number_input }} - # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. - fetch-depth: 0 - - - name: Restore timestamps - uses: thetradedesk/git-restore-mtime-action@v1.3 - - - name: Free up space - delete preinstalled tools - run: | - rm -rf /opt/hostedtoolcache - + - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main @@ -197,49 +137,32 @@ jobs: - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: - name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} + name: aws-euid-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error - outputs: - euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} - - cleanup: - name: Cleanup Building AWS Image - runs-on: ubuntu-latest - needs: [start, buildUID2EIF, buildEUIDEIF] - steps: - - name: Download UID2 artifacts - uses: actions/download-artifact@v4 - with: - path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - - name: Download EUID artifacts - uses: actions/download-artifact@v4 - with: - path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt - echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt + echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 with: - name: aws-enclave-ids-${{ needs.start.outputs.new_version }} + name: aws-enclave-ids-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests if-no-files-found: error - name: Generate release archive files - if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} run: | - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - name: Build changelog id: github_release - if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v4 with: configurationJson: | @@ -251,15 +174,15 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create release - if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v2 with: - name: ${{ needs.start.outputs.new_version }} - body: ${{ needs.start.outputs.github_changelog }} + name: ${{ steps.version.outputs.new_version }} + body: ${{ steps.github_release.outputs.changelog }} draft: true files: | - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt From 10defde1f5976dc8dadb57c676874f63c41d7d37 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 10 Apr 2024 04:24:56 +0000 Subject: [PATCH 0328/1116] [CI Pipeline] Released Patch version: 5.28.86-f0b55ad6e9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6479932d3..ae87e2678 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.83-922578729e + 5.28.86-f0b55ad6e9 UTF-8 From 53761606d2d78b3fd227c84e15f4dcac4fe22f69 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 10 Apr 2024 15:49:04 +1000 Subject: [PATCH 0329/1116] Address vulnerability issues for private operators (#483) --- scripts/azure-cc/Dockerfile | 3 ++- scripts/gcp-oidc/Dockerfile | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/azure-cc/Dockerfile b/scripts/azure-cc/Dockerfile index 2e713f4ae..b46ffeee2 100644 --- a/scripts/azure-cc/Dockerfile +++ b/scripts/azure-cc/Dockerfile @@ -1,4 +1,5 @@ -FROM eclipse-temurin@sha256:d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/11.0.22_7-jre-alpine/images/sha256-d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a?context=explore +FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 # Install Packages RUN apk update && apk add jq diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index d0ad1f86c..82c7d1d9c 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,4 +1,5 @@ -FROM eclipse-temurin@sha256:d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/11.0.22_7-jre-alpine/images/sha256-d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a?context=explore +FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL" From 79ba724e5bdb97aed0b02f46cf342b62fa30f5ae Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 10 Apr 2024 05:50:04 +0000 Subject: [PATCH 0330/1116] [CI Pipeline] Released Patch version: 5.28.89-53761606d2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ae87e2678..15dce9aa6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.86-f0b55ad6e9 + 5.28.89-53761606d2 UTF-8 From 5ac09d937be0cfd99957e2eb491cd5f6a5002796 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 11 Apr 2024 09:23:18 +1000 Subject: [PATCH 0331/1116] Updated dependencies --- .../publish-aws-nitro-enclave-docker.yaml | 17 ----------------- pom.xml | 6 +++--- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 245744764..dc7d2fba2 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -141,23 +141,6 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error - cleanup: - name: Cleanup Building AWS Image - runs-on: ubuntu-latest - needs: [start, buildUID2EIF, buildEUIDEIF] - steps: - - name: Download UID2 artifacts - uses: actions/download-artifact@v4 - with: - name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} - path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - - - name: Download EUID artifacts - uses: actions/download-artifact@v4 - with: - name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} - path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests diff --git a/pom.xml b/pom.xml index f37fa45ee..5ca91369a 100644 --- a/pom.xml +++ b/pom.xml @@ -148,17 +148,17 @@ ch.qos.logback logback-core - 1.3.12 + 1.5.3 ch.qos.logback logback-classic - 1.3.12 + 1.5.3 com.github.loki4j loki-logback-appender - 1.2.0 + 1.5.1 com.amazonaws From 5d1d10601e15475e8302656f99690a62e31794c9 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Apr 2024 14:58:34 -0600 Subject: [PATCH 0332/1116] refactoring, test fixes --- src/main/java/com/uid2/operator/Main.java | 4 ++-- .../com/uid2/operator/model/KeyManager.java | 8 +++----- .../vertx/OperatorShutdownHandler.java | 3 ++- .../operator/vertx/UIDOperatorVerticle.java | 2 +- .../operator/OperatorShutdownHandlerTest.java | 18 ++++++++++-------- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index 12dc3874b..3cc8a6e65 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -103,7 +103,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception { DownloadCloudStorage fsStores; if (coreAttestUrl != null) { - this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC()); + this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(config.getInteger(Const.Config.SaltsExpiredShutdownHours, 12)), Clock.systemUTC()); var clients = createUidClients(this.vertx, coreAttestUrl, operatorKey, this.shutdownHandler::handleAttestResponse); UidCoreClient coreClient = clients.getKey(); @@ -172,7 +172,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception { LOGGER.error("No active master key found", e); System.exit(1); } - if(saltProvider.getSnapshot(Instant.now()).getExpires().isBefore(Instant.now())) { + if (saltProvider.getSnapshot(Instant.now()).getExpires().isBefore(Instant.now())) { LOGGER.error("All salts are expired"); System.exit(1); } diff --git a/src/main/java/com/uid2/operator/model/KeyManager.java b/src/main/java/com/uid2/operator/model/KeyManager.java index 3df37798d..19bae8d07 100644 --- a/src/main/java/com/uid2/operator/model/KeyManager.java +++ b/src/main/java/com/uid2/operator/model/KeyManager.java @@ -5,14 +5,12 @@ import com.uid2.shared.auth.Keyset; import com.uid2.shared.model.KeysetKey; import com.uid2.shared.store.IKeysetKeyStore; -import com.uid2.shared.store.KeysetKeyStoreSnapshot; import com.uid2.shared.store.reader.RotatingKeysetProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.time.Instant; import java.util.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -105,7 +103,7 @@ public Map getAllKeysets() { public KeysetKey getMasterKey() { return getMasterKey(Instant.now()); } - KeysetKeyStoreSnapshot keysetKeyStoreSnapshot = new KeysetKeyStoreSnapshot(new HashMap<>(), new HashMap<>()); + public KeysetKey getMasterKey(Instant asOf) { KeysetKey key = this.keysetKeyStore.getSnapshot().getActiveKey(Const.Data.MasterKeysetId, asOf); if (key == null) { @@ -126,8 +124,8 @@ public KeysetKey getRefreshKey(Instant asOf) { return key; } - public class NoActiveKeyException extends RuntimeException { - NoActiveKeyException(String message) { + public static class NoActiveKeyException extends RuntimeException { + public NoActiveKeyException(String message) { super(message); } } diff --git a/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java b/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java index d4240aef5..218320b85 100644 --- a/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java +++ b/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java @@ -12,6 +12,7 @@ public class OperatorShutdownHandler { private static final Logger LOGGER = LoggerFactory.getLogger(OperatorShutdownHandler.class); + private static final int SALT_FAILURE_LOG_INTERVAL_MINUTES = 10; private final Duration attestShutdownWaitTime; private final Duration saltShutdownWaitTime; private final AtomicReference attestFailureStartTime = new AtomicReference<>(null); @@ -42,7 +43,7 @@ public void handleSaltRetrievalResponse(Boolean expired) { public void logSaltFailureAtInterval() { Instant t = lastSaltFailureLogTime.get(); - if(t == null || clock.instant().isAfter(t.plus(10, ChronoUnit.MINUTES))) { + if(t == null || clock.instant().isAfter(t.plus(SALT_FAILURE_LOG_INTERVAL_MINUTES, ChronoUnit.MINUTES))) { LOGGER.error("all salts are expired"); lastSaltFailureLogTime.set(Instant.now()); } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 5a6c75360..dd71944e3 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -775,7 +775,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { } else if (r.isExpired()) { ResponseUtil.Warning(ResponseStatus.ExpiredToken, 400, rc, "Expired Token presented"); } else if (r.noActiveKey()) { - SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new Exception("No active encryption key available")); + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new KeyManager.NoActiveKeyException("No active encryption key available")); } else { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } diff --git a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java index d575be5c5..d4c7199e2 100644 --- a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java +++ b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java @@ -137,14 +137,15 @@ void shutdownOnSaltsExpiredTooLong(Vertx vertx, VertxTestContext testContext) { ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); try { this.operatorShutdownHandler.handleSaltRetrievalResponse(true); } catch (RuntimeException e) { - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); - Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator")); + Assertions.assertAll("Expired Salts Log Messages", + () -> Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")), + () -> Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator"))); testContext.completeNow(); } } finally { @@ -163,15 +164,15 @@ void saltsRecoverOnSuccess(Vertx vertx, VertxTestContext testContext) { ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); - this.operatorShutdownHandler.handleSaltRetrievalResponse(false); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); assertDoesNotThrow(() -> { - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + this.operatorShutdownHandler.handleSaltRetrievalResponse(false); }); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); testContext.completeNow(); } finally { System.setSecurityManager(origSecurityManager); @@ -190,8 +191,9 @@ void saltsLogErrorAtInterval(Vertx vertx, VertxTestContext testContext) { this.operatorShutdownHandler.handleSaltRetrievalResponse(true); Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertEquals(1, logWatcher.list.size()); when(clock.instant()).thenAnswer(i -> Instant.now().plus(9, ChronoUnit.MINUTES)); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); Assertions.assertEquals(1, logWatcher.list.size()); when(clock.instant()).thenAnswer(i -> Instant.now().plus(11, ChronoUnit.MINUTES)); this.operatorShutdownHandler.handleSaltRetrievalResponse(true); From 78e52cf17b41793ffb332db10f38dc7e77f71f49 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Apr 2024 15:03:06 -0600 Subject: [PATCH 0333/1116] salt shutdown hours configs --- conf/docker-config.json | 3 ++- conf/integ-config.json | 3 ++- conf/local-config.json | 3 ++- conf/local-e2e-docker-private-config.json | 3 ++- conf/local-e2e-docker-public-config.json | 3 ++- conf/local-e2e-private-config.json | 3 ++- conf/local-e2e-public-config.json | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/conf/docker-config.json b/conf/docker-config.json index ab658e513..e97d64187 100644 --- a/conf/docker-config.json +++ b/conf/docker-config.json @@ -36,5 +36,6 @@ "optout_metadata_path": null, "optout_inmem_cache": false, "enclave_platform": null, - "failure_shutdown_wait_hours": 120 + "failure_shutdown_wait_hours": 120, + "salts_expired_shutdown_hours": 12 } diff --git a/conf/integ-config.json b/conf/integ-config.json index f6dba38f3..c16a16d9a 100644 --- a/conf/integ-config.json +++ b/conf/integ-config.json @@ -12,5 +12,6 @@ "core_attest_url": "http://localhost:8088/attest", "core_api_token": "trusted-partner-key", "optout_api_token": "test-operator-key", - "optout_api_uri": "http://localhost:8081/optout/replicate" + "optout_api_uri": "http://localhost:8081/optout/replicate", + "salts_expired_shutdown_hours": 12 } \ No newline at end of file diff --git a/conf/local-config.json b/conf/local-config.json index af46c8f61..eca081f74 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -35,5 +35,6 @@ "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, "key_sharing_endpoint_provide_site_domain_names": true, - "client_side_token_generate_log_invalid_http_origins": true + "client_side_token_generate_log_invalid_http_origins": true, + "salts_expired_shutdown_hours": 12 } diff --git a/conf/local-e2e-docker-private-config.json b/conf/local-e2e-docker-private-config.json index 947c2af3c..b777533fe 100644 --- a/conf/local-e2e-docker-private-config.json +++ b/conf/local-e2e-docker-private-config.json @@ -26,5 +26,6 @@ "optout_metadata_path": "/optout/refresh", "optout_api_uri": "http://optout:8081/optout/replicate", "optout_delta_rotate_interval": 60, - "cloud_refresh_interval": 30 + "cloud_refresh_interval": 30, + "salts_expired_shutdown_hours": 12 } diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index 70eaa049e..8190951fe 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -31,5 +31,6 @@ "optout_metadata_path": "/optout/refresh", "optout_api_uri": "http://optout:8081/optout/replicate", "optout_delta_rotate_interval": 60, - "cloud_refresh_interval": 30 + "cloud_refresh_interval": 30, + "salts_expired_shutdown_hours": 12 } diff --git a/conf/local-e2e-private-config.json b/conf/local-e2e-private-config.json index 32b65e691..920a159e7 100644 --- a/conf/local-e2e-private-config.json +++ b/conf/local-e2e-private-config.json @@ -37,5 +37,6 @@ "optout_partition_interval": 86400, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": false, - "client_side_token_generate_log_invalid_http_origins": true + "client_side_token_generate_log_invalid_http_origins": true, + "salts_expired_shutdown_hours": 12 } diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index a57f636aa..e8ba64930 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -38,5 +38,6 @@ "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, "key_sharing_endpoint_provide_site_domain_names": true, - "client_side_token_generate_log_invalid_http_origins": true + "client_side_token_generate_log_invalid_http_origins": true, + "salts_expired_shutdown_hours": 12 } From 4983283a007982602f63a32ac066fdb264161358 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Apr 2024 15:14:00 -0600 Subject: [PATCH 0334/1116] test fixes --- .../java/com/uid2/operator/UIDOperatorServiceTest.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index af2cd0ce2..c7cc00bd2 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -39,7 +39,6 @@ public class UIDOperatorServiceTest { private AutoCloseable mocks; @Mock private IOptOutStore optOutStore; @Mock private Clock clock; - @Mock private OperatorShutdownHandler shutdownHandler; EncryptedTokenEncoder tokenEncoder; UIDOperatorService uid2Service; UIDOperatorService euidService; @@ -82,8 +81,6 @@ void setup() throws Exception { uid2Config.put("advertising_token_v3", false); // prod is using v2 token version for now uid2Config.put("identity_v3", false); - this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC()); - uid2Service = new UIDOperatorService( uid2Config, optOutStore, @@ -91,7 +88,7 @@ void setup() throws Exception { tokenEncoder, this.clock, IdentityScope.UID2, - this.shutdownHandler::handleSaltRetrievalResponse + new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC())::handleSaltRetrievalResponse ); final JsonObject euidConfig = new JsonObject(); @@ -102,8 +99,6 @@ void setup() throws Exception { euidConfig.put("advertising_token_v3", true); euidConfig.put("identity_v3", true); - this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC()); - euidService = new UIDOperatorService( euidConfig, optOutStore, @@ -111,7 +106,7 @@ void setup() throws Exception { tokenEncoder, this.clock, IdentityScope.EUID, - this.shutdownHandler::handleSaltRetrievalResponse + new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC())::handleSaltRetrievalResponse ); } From 573efedeefec4318c467a9c9002c620ec4dc1b7f Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Apr 2024 17:05:02 -0600 Subject: [PATCH 0335/1116] testing in UIDOperatorServiceTest.java --- .../test/salts/metadataExpired.json | 13 ++ .../uid2/operator/UIDOperatorServiceTest.java | 151 +++++++++++++++++- 2 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/com.uid2.core/test/salts/metadataExpired.json diff --git a/src/main/resources/com.uid2.core/test/salts/metadataExpired.json b/src/main/resources/com.uid2.core/test/salts/metadataExpired.json new file mode 100644 index 000000000..282989606 --- /dev/null +++ b/src/main/resources/com.uid2.core/test/salts/metadataExpired.json @@ -0,0 +1,13 @@ +{ + "version" : 1, + "generated" : 1670883129, + "first_level" : "fOGY/aRE44peL23i+cE9MkJrzmEeNZZziNZBfq7qqk8=", + "id_prefix" : "b", + "id_secret" : "HF6Qz42HBbVHINxhh191dB09BCuTWyBkNtrNicO4ZCw=", + "salts" : [{ + "effective" : 1670796729291, + "expires" : 1670796729292, + "location" : "/com.uid2.core/test/salts/salts.txt.1670796729291", + "size" : 2 + }] +} \ No newline at end of file diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index c7cc00bd2..62f7a884c 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -33,13 +33,16 @@ import java.time.temporal.ChronoUnit; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class UIDOperatorServiceTest { private AutoCloseable mocks; @Mock private IOptOutStore optOutStore; @Mock private Clock clock; + @Mock private OperatorShutdownHandler shutdownHandler; EncryptedTokenEncoder tokenEncoder; + JsonObject uid2Config; + JsonObject euidConfig; UIDOperatorService uid2Service; UIDOperatorService euidService; Instant now; @@ -73,7 +76,7 @@ void setup() throws Exception { setNow(Instant.now()); - final JsonObject uid2Config = new JsonObject(); + uid2Config = new JsonObject(); uid2Config.put(UIDOperatorService.IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS, IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS); uid2Config.put(UIDOperatorService.REFRESH_TOKEN_EXPIRES_AFTER_SECONDS, REFRESH_TOKEN_EXPIRES_AFTER_SECONDS); uid2Config.put(UIDOperatorService.REFRESH_IDENTITY_TOKEN_AFTER_SECONDS, REFRESH_IDENTITY_TOKEN_AFTER_SECONDS); @@ -88,10 +91,10 @@ void setup() throws Exception { tokenEncoder, this.clock, IdentityScope.UID2, - new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC())::handleSaltRetrievalResponse + this.shutdownHandler::handleSaltRetrievalResponse ); - final JsonObject euidConfig = new JsonObject(); + euidConfig = new JsonObject(); euidConfig.put(UIDOperatorService.IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS, IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS); euidConfig.put(UIDOperatorService.REFRESH_TOKEN_EXPIRES_AFTER_SECONDS, REFRESH_TOKEN_EXPIRES_AFTER_SECONDS); euidConfig.put(UIDOperatorService.REFRESH_IDENTITY_TOKEN_AFTER_SECONDS, REFRESH_IDENTITY_TOKEN_AFTER_SECONDS); @@ -106,7 +109,7 @@ void setup() throws Exception { tokenEncoder, this.clock, IdentityScope.EUID, - new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), Clock.systemUTC())::handleSaltRetrievalResponse + this.shutdownHandler::handleSaltRetrievalResponse ); } @@ -145,6 +148,8 @@ public void testGenerateAndRefresh() { OptoutCheckPolicy.DoNotRespect ); final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); AdvertisingToken advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email); @@ -164,7 +169,10 @@ public void testGenerateAndRefresh() { setNow(Instant.now().plusSeconds(200)); + reset(shutdownHandler); final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshToken); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(refreshResponse); assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); assertNotNull(refreshResponse.getTokens()); @@ -197,6 +205,8 @@ public void testTestOptOutKey() { OptoutCheckPolicy.DoNotRespect ); final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); @@ -214,10 +224,14 @@ public void testTestOptOutKeyIdentityScopeMismatch() { OptoutCheckPolicy.DoNotRespect ); final IdentityTokens tokens = euidService.generateIdentity(identityRequest); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + reset(shutdownHandler); assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshToken)); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @ParameterizedTest @@ -247,14 +261,22 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String identity, I final IdentityTokens tokensAfterOptOut; if (scope == IdentityScope.UID2) { tokens = uid2Service.generateIdentity(identityRequestForceGenerate); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, userIdentity.identityType); + reset(shutdownHandler); tokensAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); } else { tokens = euidService.generateIdentity(identityRequestForceGenerate); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, userIdentity.identityType); + reset(shutdownHandler); tokensAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); assertNotNull(advertisingToken.userIdentity); assertNotNull(tokensAfterOptOut); @@ -288,12 +310,20 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide final MappedIdentity mappedIdentity; final MappedIdentity mappedIdentityShouldBeOptOut; if (scope == IdentityScope.UID2) { + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); mappedIdentity = uid2Service.mapIdentity(mapRequestForceMap); + reset(shutdownHandler); mappedIdentityShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); } else { + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); mappedIdentity = euidService.mapIdentity(mapRequestForceMap); + reset(shutdownHandler); mappedIdentityShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(mappedIdentity); assertFalse(mappedIdentity.isOptedOut()); assertNotNull(mappedIdentityShouldBeOptOut); @@ -359,6 +389,8 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i else { tokens = uid2Service.generateIdentity(identityRequest); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertEquals(tokens, IdentityTokens.LogoutToken); } @@ -389,6 +421,8 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, else { mappedIdentity = uid2Service.mapIdentity(mapRequestRespectOptOut); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(mappedIdentity); assertTrue(mappedIdentity.isOptedOut()); } @@ -418,6 +452,8 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id else { tokens = uid2Service.generateIdentity(identityRequest); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); assertNotEquals(IdentityTokens.LogoutToken, tokens); @@ -425,7 +461,9 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id when(this.optOutStore.getLatestEntry(any())).thenReturn(null); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + reset(shutdownHandler); assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken)); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @ParameterizedTest @@ -456,6 +494,8 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String else { tokens = uid2Service.generateIdentity(identityRequest); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); assertNotEquals(IdentityTokens.LogoutToken, tokens); @@ -463,7 +503,9 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String when(this.optOutStore.getLatestEntry(any())).thenReturn(null); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + reset(shutdownHandler); assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken)); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @ParameterizedTest @@ -493,6 +535,8 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str else { mappedIdentity = uid2Service.mapIdentity(mapRequestRespectOptOut); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(mappedIdentity); assertFalse(mappedIdentity.isOptedOut()); } @@ -528,6 +572,8 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, tokens = uid2Service.generateIdentity(identityRequest); advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); assertNotEquals(IdentityTokens.LogoutToken, tokens); assertNotNull(advertisingToken.userIdentity); @@ -561,6 +607,8 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i else { mappedIdentity = uid2Service.mapIdentity(mapRequestRespectOptOut); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(mappedIdentity); assertFalse(mappedIdentity.isOptedOut()); } @@ -586,13 +634,106 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop else { tokens = uid2Service.generateIdentity(identityRequest); } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotEquals(tokens, IdentityTokens.LogoutToken); assertNotNull(tokens); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + reset(shutdownHandler); RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getTokens()); assertNotEquals(RefreshResponse.Optout, refreshResponse); } + + @ParameterizedTest + @CsvSource({"Email,blah@unifiedid.com,UID2", + "EmailHash,blah@unifiedid.com,UID2", + "Phone,+61401234567,EUID", + "PhoneHash,+61401234567,EUID", + "Email,blah@unifiedid.com,EUID", + "EmailHash,blah@unifiedid.com,EUID"}) + void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String id, IdentityScope scope) throws Exception { + RotatingSaltProvider saltProvider = new RotatingSaltProvider( + new EmbeddedResourceStorage(Main.class), + "/com.uid2.core/test/salts/metadataExpired.json"); + saltProvider.loadContent(); + + UIDOperatorService uid2Service = new UIDOperatorService( + uid2Config, + optOutStore, + saltProvider, + tokenEncoder, + this.clock, + IdentityScope.UID2, + this.shutdownHandler::handleSaltRetrievalResponse + ); + + UIDOperatorService euidService = new UIDOperatorService( + euidConfig, + optOutStore, + saltProvider, + tokenEncoder, + this.clock, + IdentityScope.EUID, + this.shutdownHandler::handleSaltRetrievalResponse + ); + + when(this.optOutStore.getLatestEntry(any())).thenReturn(null); + + InputUtil.InputVal inputVal = generateInputVal(type, id); + + final IdentityRequest identityRequest = new IdentityRequest( + new PublisherIdentity(123, 124, 125), + inputVal.toUserIdentity(scope, 0, this.now), + OptoutCheckPolicy.RespectOptOut); + + IdentityTokens tokens; + AdvertisingToken advertisingToken; + reset(shutdownHandler); + if(scope == IdentityScope.EUID) { + tokens = euidService.generateIdentity(identityRequest); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, identityRequest.userIdentity.identityType); + } + else { + tokens = uid2Service.generateIdentity(identityRequest); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, identityRequest.userIdentity.identityType); + } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); + assertNotNull(tokens); + assertNotEquals(IdentityTokens.LogoutToken, tokens); + assertNotNull(advertisingToken.userIdentity); + + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + reset(shutdownHandler); + RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); + assertTrue(refreshResponse.isRefreshed()); + assertNotNull(refreshResponse.getTokens()); + assertNotEquals(RefreshResponse.Optout, refreshResponse); + + final MapRequest mapRequest = new MapRequest( + inputVal.toUserIdentity(scope, 0, this.now), + OptoutCheckPolicy.RespectOptOut, + now); + + final MappedIdentity mappedIdentity; + reset(shutdownHandler); + if(scope == IdentityScope.EUID) { + mappedIdentity = euidService.mapIdentity(mapRequest); + } + else { + mappedIdentity = uid2Service.mapIdentity(mapRequest); + } + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); + assertNotNull(mappedIdentity); + assertFalse(mappedIdentity.isOptedOut()); + + } } From 5dfd893878ca344229f85cd4da822f71731c7929 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Apr 2024 17:12:12 -0600 Subject: [PATCH 0336/1116] small test refactor --- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 62f7a884c..8b00bbbf8 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -28,7 +28,6 @@ import java.nio.charset.StandardCharsets; import java.security.Security; import java.time.Clock; -import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -564,14 +563,13 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, IdentityTokens tokens; AdvertisingToken advertisingToken; - if(scope == IdentityScope.EUID) { + if (scope == IdentityScope.EUID) { tokens = euidService.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType); } else { tokens = uid2Service.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType); } + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); From d2f6e61b967479c0b3b8a066998394b81ed6c0c5 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Apr 2024 17:15:17 -0600 Subject: [PATCH 0337/1116] whitespace --- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 8b00bbbf8..6d476450c 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -719,7 +719,6 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toUserIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); - final MappedIdentity mappedIdentity; reset(shutdownHandler); if(scope == IdentityScope.EUID) { From 07df883c4010e1824a38d0e1621e43feb463bb83 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 14 Apr 2024 13:06:29 -0600 Subject: [PATCH 0338/1116] remove unused import --- src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java b/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java index 905013821..855ea1187 100644 --- a/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java +++ b/src/main/java/com/uid2/operator/vertx/GenericFailureHandler.java @@ -1,6 +1,5 @@ package com.uid2.operator.vertx; -import com.uid2.operator.model.KeyManager; import io.vertx.core.Handler; import io.vertx.core.http.HttpClosedException; import io.vertx.core.http.HttpServerResponse; From d9423112f1fd7381158c4f3112eaf91d6a3d3b8b Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 14 Apr 2024 13:35:40 -0600 Subject: [PATCH 0339/1116] test improvements --- .../operator/OperatorShutdownHandlerTest.java | 18 ++++++++++-------- .../uid2/operator/UIDOperatorServiceTest.java | 9 +-------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java index d4c7199e2..d7a7797ea 100644 --- a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java +++ b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java @@ -140,14 +140,15 @@ void shutdownOnSaltsExpiredTooLong(Vertx vertx, VertxTestContext testContext) { Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); - try { + Assertions.assertThrows(RuntimeException.class, () -> { this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - } catch (RuntimeException e) { - Assertions.assertAll("Expired Salts Log Messages", - () -> Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")), - () -> Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator"))); - testContext.completeNow(); - } + }); + Assertions.assertAll("Expired Salts Log Messages", + () -> Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")), + () -> Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator")), + () -> Assertions.assertEquals(3, logWatcher.list.size())); + + testContext.completeNow(); } finally { System.setSecurityManager(origSecurityManager); } @@ -173,6 +174,8 @@ void saltsRecoverOnSuccess(Vertx vertx, VertxTestContext testContext) { assertDoesNotThrow(() -> { this.operatorShutdownHandler.handleSaltRetrievalResponse(false); }); + Assertions.assertEquals(2, logWatcher.list.size()); + testContext.completeNow(); } finally { System.setSecurityManager(origSecurityManager); @@ -191,7 +194,6 @@ void saltsLogErrorAtInterval(Vertx vertx, VertxTestContext testContext) { this.operatorShutdownHandler.handleSaltRetrievalResponse(true); Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - Assertions.assertEquals(1, logWatcher.list.size()); when(clock.instant()).thenAnswer(i -> Instant.now().plus(9, ChronoUnit.MINUTES)); this.operatorShutdownHandler.handleSaltRetrievalResponse(true); Assertions.assertEquals(1, logWatcher.list.size()); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 6d476450c..eaa13608d 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -637,14 +637,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop assertNotEquals(tokens, IdentityTokens.LogoutToken); assertNotNull(tokens); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); - reset(shutdownHandler); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); - verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); - verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertTrue(refreshResponse.isRefreshed()); - assertNotNull(refreshResponse.getTokens()); - assertNotEquals(RefreshResponse.Optout, refreshResponse); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken());; } @ParameterizedTest From 62e50c5b5851b992784119c342627447860971c3 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 14 Apr 2024 13:36:25 -0600 Subject: [PATCH 0340/1116] test improvements --- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index eaa13608d..98e3525d5 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -636,8 +636,6 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotEquals(tokens, IdentityTokens.LogoutToken); assertNotNull(tokens); - - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken());; } @ParameterizedTest From 75588ff3e1c00ee6801c11c9ecbb8bd681bbd001 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 14 Apr 2024 13:38:39 -0600 Subject: [PATCH 0341/1116] test improvements --- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 98e3525d5..50048283a 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -636,6 +636,12 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotEquals(tokens, IdentityTokens.LogoutToken); assertNotNull(tokens); + + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); + assertTrue(refreshResponse.isRefreshed()); + assertNotNull(refreshResponse.getTokens()); + assertNotEquals(RefreshResponse.Optout, refreshResponse); } @ParameterizedTest From be2b8f6372105f756dc18a7473e80a06f81a124f Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 15 Apr 2024 14:22:30 +1000 Subject: [PATCH 0342/1116] Update aws-java-sdk-s3 version to address vulnerability issue (#488) * Update base eclipse-temurin version * Update aws-java-sdk-s3 to 1.12.701 * Revert updating dockerfile base image --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 15dce9aa6..91dd2a03d 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ com.amazonaws aws-java-sdk-s3 - 1.12.368 + 1.12.701 com.iabtcf From e3a958988739c43c8ec2d93e5327b1e841a0b9dc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Apr 2024 10:39:07 +1000 Subject: [PATCH 0343/1116] Adding udp port --- scripts/aws/proxies.host.yaml | 7 ++++- scripts/aws/proxies.nitro.yaml | 7 ++++- scripts/aws/syslog-ng/syslog-ng-client.conf | 30 +++++++-------------- scripts/aws/syslog-ng/syslog-ng-server.conf | 2 +- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/scripts/aws/proxies.host.yaml b/scripts/aws/proxies.host.yaml index 7069a6fde..4dcaa629b 100644 --- a/scripts/aws/proxies.host.yaml +++ b/scripts/aws/proxies.host.yaml @@ -23,4 +23,9 @@ loki: syslogng: service: direct listen: vsock://42:2011 - connect: tcp://127.0.0.1:2011 \ No newline at end of file + connect: tcp://127.0.0.1:2011 + +syslogngudp: + service: direct + listen: vsock://42:2011 + connect: udp://127.0.0.1:2010 \ No newline at end of file diff --git a/scripts/aws/proxies.nitro.yaml b/scripts/aws/proxies.nitro.yaml index 9772f3bb1..2ad63b9bc 100644 --- a/scripts/aws/proxies.nitro.yaml +++ b/scripts/aws/proxies.nitro.yaml @@ -28,4 +28,9 @@ loki: syslogng: service: direct listen: tcp://127.0.0.1:2011 - connect: vsock://3:2011 \ No newline at end of file + connect: vsock://3:2011 + +syslogngudp: + service: direct + listen: udp://127.0.0.1:2010 + connect: vsock://3:2010 \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index c173dfae3..980723c85 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -1,4 +1,4 @@ -@version: 3.28 +@version: 4.6 @include "scl.conf" source s_local { @@ -6,32 +6,20 @@ source s_local { internal(); }; -source s_syslog_udp { - syslog( - ip(0.0.0.0) - port(2010) - transport("udp") - ); -}; - -source s_file { - file("/var/log/uid2operator.log"); -}; - destination d_syslog_tcp { syslog("127.0.0.1" port(2011) transport("tcp")); }; -destination d_syslog_udp { - syslog("127.0.0.1" port(2010) transport("udp")); +source s_stdout { + pipe("/dev/stdout"); + pipe("/dev/stderr"); }; -destination d_file { - file("/var/log/sysng.log"); +destination d_syslog_udp { + syslog("ngserver" port(2010) transport("udp")); }; log { source(s_local); - source(s_syslog_udp); - source(s_file); - destination(d_syslog_tcp); -}; + source(s_stdout); + destination(d_syslog_udp); +}; \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index 2adc91950..623ae76c7 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -1,4 +1,4 @@ -@version: 3.35 +@version: 4.6 @include "scl.conf" options { From 21b6b9e4ad69c1c8662bfafc1c3e03708c8eda70 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Apr 2024 00:40:40 +0000 Subject: [PATCH 0344/1116] [CI Pipeline] Released Snapshot version: 5.28.114-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 309b32214..f4f148204 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.89-53761606d2 + 5.28.114-SNAPSHOT UTF-8 From f9e8851761c1f072c0081e4e337a1e8f80676143 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Apr 2024 14:50:01 +1000 Subject: [PATCH 0345/1116] Updated the eif docker image to install syslog-ng --- scripts/aws/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 775970edf..89ba288c2 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -14,8 +14,10 @@ ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} ENV ENCLAVE_ENVIRONMENT="aws-nitro" ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" -RUN apt update -y \ - && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip syslog-ng \ +RUN curl https://ose-repo.syslog-ng.com/apt/syslog-ng-ose-pub.asc | apt-key add - \ + && echo "deb https://ose-repo.syslog-ng.com/apt/ stable debian-bullseye" | tee -a /etc/apt/sources.list.d/syslog-ng-ose.list \ + && apt update -y \ + && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip syslog-ng-core=4.6.0-1 \ && rm -rf /var/lib/apt/lists/* RUN pip3 install boto3==1.16.9 From 4982bc20064fa41968b0a952a0cee48fd74c2ed6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Apr 2024 04:51:06 +0000 Subject: [PATCH 0346/1116] [CI Pipeline] Released Snapshot version: 5.28.116-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f4f148204..3dbab9e4d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.114-SNAPSHOT + 5.28.116-SNAPSHOT UTF-8 From 8046e0880d775482d341906816dd0fc989137bd1 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Apr 2024 15:03:25 +1000 Subject: [PATCH 0347/1116] Changed order for updates --- scripts/aws/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 89ba288c2..22a9f2b61 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -14,10 +14,12 @@ ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} ENV ENCLAVE_ENVIRONMENT="aws-nitro" ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" -RUN curl https://ose-repo.syslog-ng.com/apt/syslog-ng-ose-pub.asc | apt-key add - \ +RUN apt update -y \ + && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip \ + && curl https://ose-repo.syslog-ng.com/apt/syslog-ng-ose-pub.asc | apt-key add - \ && echo "deb https://ose-repo.syslog-ng.com/apt/ stable debian-bullseye" | tee -a /etc/apt/sources.list.d/syslog-ng-ose.list \ - && apt update -y \ - && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip syslog-ng-core=4.6.0-1 \ + && apt-update -y \ + && apt install -y syslog-ng-core=4.6.0-1 \ && rm -rf /var/lib/apt/lists/* RUN pip3 install boto3==1.16.9 From 3a585e249e8cc9cb74d6db53499adea5b53cab3b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Apr 2024 05:04:30 +0000 Subject: [PATCH 0348/1116] [CI Pipeline] Released Snapshot version: 5.28.118-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3dbab9e4d..525fb9bde 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.116-SNAPSHOT + 5.28.118-SNAPSHOT UTF-8 From 76c4c499125e1fa36333304add5087ce712bff4d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Apr 2024 15:12:25 +1000 Subject: [PATCH 0349/1116] Fixed typo in apt update --- scripts/aws/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 22a9f2b61..72dc90541 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -18,7 +18,7 @@ RUN apt update -y \ && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip \ && curl https://ose-repo.syslog-ng.com/apt/syslog-ng-ose-pub.asc | apt-key add - \ && echo "deb https://ose-repo.syslog-ng.com/apt/ stable debian-bullseye" | tee -a /etc/apt/sources.list.d/syslog-ng-ose.list \ - && apt-update -y \ + && apt update -y \ && apt install -y syslog-ng-core=4.6.0-1 \ && rm -rf /var/lib/apt/lists/* RUN pip3 install boto3==1.16.9 From a72a49489209e371587faf0b298da6897e1435a9 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Apr 2024 05:14:16 +0000 Subject: [PATCH 0350/1116] [CI Pipeline] Released Snapshot version: 5.28.120-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 525fb9bde..1b0ea4db2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.118-SNAPSHOT + 5.28.120-SNAPSHOT UTF-8 From d0b910e1f2bf62c9d9a72a4ae727208f87a99d17 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 16 Apr 2024 19:25:36 +1000 Subject: [PATCH 0351/1116] Enable log redirect (#486) --- scripts/gcp-oidc/Dockerfile | 1 + scripts/gcp-oidc/README.md | 4 ++-- scripts/gcp-oidc/terraform/main.tf | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index 82c7d1d9c..b8fa9c54a 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -2,6 +2,7 @@ FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL" +LABEL "tee.launch_policy.log_redirect"="always" # Install Packages RUN apk update && apk add jq diff --git a/scripts/gcp-oidc/README.md b/scripts/gcp-oidc/README.md index 4dcc3256b..1a6e35c0c 100644 --- a/scripts/gcp-oidc/README.md +++ b/scripts/gcp-oidc/README.md @@ -185,7 +185,7 @@ $ gcloud compute instances create {INSTANCE_NAME} \ --image-project confidential-space-images \ --image-family confidential-space \ --service-account {SERVICE_ACCOUNT} \ - --metadata ^~^tee-image-reference={OPERATOR_IMAGE}~tee-restart-policy=Never~tee-env-DEPLOYMENT_ENVIRONMENT=integ~tee-env-API_TOKEN_SECRET_NAME={OPERATOR_KEY_SECRET_FULL_NAME} + --metadata ^~^tee-image-reference={OPERATOR_IMAGE}~tee-restart-policy=Never~tee-container-log-redirect=true~tee-env-DEPLOYMENT_ENVIRONMENT=integ~tee-env-API_TOKEN_SECRET_NAME={OPERATOR_KEY_SECRET_FULL_NAME} ``` ## Production Deployment @@ -212,7 +212,7 @@ $ gcloud compute instances create {INSTANCE_NAME} \ --image-project confidential-space-images \ --image-family confidential-space \ --service-account {SERVICE_ACCOUNT} \ - --metadata ^~^tee-image-reference={OPERATOR_IMAGE}~tee-restart-policy=Never~tee-env-DEPLOYMENT_ENVIRONMENT=prod~tee-env-API_TOKEN_SECRET_NAME={OPERATOR_KEY_SECRET_FULL_NAME} + --metadata ^~^tee-image-reference={OPERATOR_IMAGE}~tee-restart-policy=Never~tee-container-log-redirect=true~tee-env-DEPLOYMENT_ENVIRONMENT=prod~tee-env-API_TOKEN_SECRET_NAME={OPERATOR_KEY_SECRET_FULL_NAME} ``` Note that compared to the `gcloud` command used in the prior section, parameter `--machine-type n2d-standard-16` is set to ensure production deployment of UID2 Operator runs on the recommended machine type for production. diff --git a/scripts/gcp-oidc/terraform/main.tf b/scripts/gcp-oidc/terraform/main.tf index 73fafc076..c32d6eb77 100644 --- a/scripts/gcp-oidc/terraform/main.tf +++ b/scripts/gcp-oidc/terraform/main.tf @@ -104,7 +104,7 @@ resource "google_compute_instance_template" "uid_operator" { metadata = { tee-image-reference = var.uid_operator_image - tee-container-log-redirect = var.debug_mode + tee-container-log-redirect = true tee-restart-policy = "Never" tee-env-DEPLOYMENT_ENVIRONMENT = var.uid_deployment_env tee-env-API_TOKEN_SECRET_NAME = module.secret-manager.secret_versions[0] From 356635e7e7b966ce9e6678d744faa7ae2838ce78 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 17 Apr 2024 11:29:36 +1000 Subject: [PATCH 0352/1116] Change to syslog over tcp --- pom.xml | 17 +++++-- scripts/aws/Dockerfile | 4 +- scripts/aws/conf/logback.loki.xml | 53 ++++----------------- scripts/aws/proxies.host.yaml | 5 -- scripts/aws/proxies.nitro.yaml | 5 -- scripts/aws/syslog-ng/syslog-ng-client.conf | 10 +--- scripts/aws/syslog-ng/syslog-ng-server.conf | 16 ++----- 7 files changed, 29 insertions(+), 81 deletions(-) diff --git a/pom.xml b/pom.xml index 525fb9bde..15fe5af92 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.uid2 @@ -31,8 +30,12 @@ snapshots-repo https://s01.oss.sonatype.org/content/repositories/snapshots - false - true + + false + + + true + @@ -160,6 +163,12 @@ loki-logback-appender 1.5.1 + + net.logstash.logback + logstash-logback-encoder + 7.4 + runtime + com.amazonaws aws-java-sdk-s3 diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 72dc90541..e2a25cc32 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:11.0-jre-slim-bullseye +FROM openjdk:11.0.16-jre-slim-bullseye WORKDIR /app @@ -39,8 +39,6 @@ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf -EXPOSE 2011 - RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh CMD ["/app/entrypoint.sh"] diff --git a/scripts/aws/conf/logback.loki.xml b/scripts/aws/conf/logback.loki.xml index cbe4d179e..6d6eb0d29 100644 --- a/scripts/aws/conf/logback.loki.xml +++ b/scripts/aws/conf/logback.loki.xml @@ -1,49 +1,16 @@ - - - http://127.0.0.1:3100/loki/api/v1/push - - - - - l=%level h=${HOSTNAME} po=${port_offset:-0} c=%logger{20} t=%thread | %msg %ex - - true - - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %ex%n - - - - - 127.0.0.1 - 2010 - SYSLOG - [%level] [%level] [%logger] [%thread] %msg %ex - - - /var/log/uid2operator.log - true - - true - - - %-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n + + + + 127.0.0.1:2011 + + + REDACTED - S3 + \S+s3\.amazonaws\.com\/\S*X-Amz-Security-Token=\S+ + - - - - - + \ No newline at end of file diff --git a/scripts/aws/proxies.host.yaml b/scripts/aws/proxies.host.yaml index 4dcaa629b..c9d9b52f8 100644 --- a/scripts/aws/proxies.host.yaml +++ b/scripts/aws/proxies.host.yaml @@ -24,8 +24,3 @@ syslogng: service: direct listen: vsock://42:2011 connect: tcp://127.0.0.1:2011 - -syslogngudp: - service: direct - listen: vsock://42:2011 - connect: udp://127.0.0.1:2010 \ No newline at end of file diff --git a/scripts/aws/proxies.nitro.yaml b/scripts/aws/proxies.nitro.yaml index 2ad63b9bc..093211c11 100644 --- a/scripts/aws/proxies.nitro.yaml +++ b/scripts/aws/proxies.nitro.yaml @@ -29,8 +29,3 @@ syslogng: service: direct listen: tcp://127.0.0.1:2011 connect: vsock://3:2011 - -syslogngudp: - service: direct - listen: udp://127.0.0.1:2010 - connect: vsock://3:2010 \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 980723c85..911dc0dbe 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -9,17 +9,9 @@ source s_local { destination d_syslog_tcp { syslog("127.0.0.1" port(2011) transport("tcp")); }; -source s_stdout { - pipe("/dev/stdout"); - pipe("/dev/stderr"); -}; - -destination d_syslog_udp { - syslog("ngserver" port(2010) transport("udp")); -}; log { source(s_local); source(s_stdout); - destination(d_syslog_udp); + destination(d_syslog_tcp); }; \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index 623ae76c7..2048b1a0b 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -14,19 +14,12 @@ source s_local { internal(); }; -source s_network_udp { - syslog( - ip(0.0.0.0) - port(2010) - transport("udp") - ); -}; - -source s_network_tcp { - syslog( +source s_network { + networ( ip(0.0.0.0) port(2011) transport("tcp") + flags(syslog-protocol) ); }; @@ -36,7 +29,6 @@ destination d_local { log { source(s_local); - source(s_network_udp); - source(s_network_tcp); + source(s_network); destination(d_local); }; \ No newline at end of file From e3161afff7c446694750abb5d26376f2f0d41928 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Apr 2024 01:30:40 +0000 Subject: [PATCH 0353/1116] [CI Pipeline] Released Snapshot version: 5.28.122-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 54af23973..a2901d91c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.uid2 uid2-operator - 5.28.120-SNAPSHOT + 5.28.122-SNAPSHOT UTF-8 From 5e3a57b7ee9c05f5e737754b994a8fd3e164fd47 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 17 Apr 2024 12:02:12 +1000 Subject: [PATCH 0354/1116] Fixed typo --- scripts/aws/syslog-ng/syslog-ng-client.conf | 1 - scripts/aws/syslog-ng/syslog-ng-server.conf | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 911dc0dbe..f6a9c37d6 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -12,6 +12,5 @@ destination d_syslog_tcp { log { source(s_local); - source(s_stdout); destination(d_syslog_tcp); }; \ No newline at end of file diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index 2048b1a0b..88a50a0af 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -11,11 +11,11 @@ options { source s_local { system(); - internal(); + internal(); }; source s_network { - networ( + network( ip(0.0.0.0) port(2011) transport("tcp") From 98ccab14e001d9224e270e51fda712c2ecbcc6a1 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Apr 2024 02:02:54 +0000 Subject: [PATCH 0355/1116] [CI Pipeline] Released Snapshot version: 5.28.124-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a2901d91c..bc14afc5a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.uid2 uid2-operator - 5.28.122-SNAPSHOT + 5.28.124-SNAPSHOT UTF-8 From ead04295603c2405f883d93f415fdf4b3a1dd938 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 17 Apr 2024 14:54:29 +1000 Subject: [PATCH 0356/1116] Adding stdout source --- scripts/aws/proxies.host.yaml | 9 ++------- scripts/aws/proxies.nitro.yaml | 5 ----- scripts/aws/syslog-ng/syslog-ng-client.conf | 6 ++++++ 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/scripts/aws/proxies.host.yaml b/scripts/aws/proxies.host.yaml index c9d9b52f8..5a2ae0623 100644 --- a/scripts/aws/proxies.host.yaml +++ b/scripts/aws/proxies.host.yaml @@ -2,7 +2,7 @@ socks5h-proxy: service: direct - listen: vsock://42:3305 + listen: vsock://-1:3305 connect: tcp://127.0.0.1:3306 operator-service: @@ -15,12 +15,7 @@ operator-prometheus: listen: tcp://0.0.0.0:9080 connect: vsock://42:9080 -loki: - service: direct - listen: vsock://42:3100 - connect: tcp://127.0.0.1:3100 - syslogng: service: direct - listen: vsock://42:2011 + listen: vsock://-1:2011 connect: tcp://127.0.0.1:2011 diff --git a/scripts/aws/proxies.nitro.yaml b/scripts/aws/proxies.nitro.yaml index 093211c11..feca3a75d 100644 --- a/scripts/aws/proxies.nitro.yaml +++ b/scripts/aws/proxies.nitro.yaml @@ -20,11 +20,6 @@ aws-service-proxy: listen: tcp://127.0.0.1:443 connect: vsock://3:3308 -loki: - service: direct - listen: tcp://127.0.0.1:3100 - connect: vsock://3:3100 - syslogng: service: direct listen: tcp://127.0.0.1:2011 diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index f6a9c37d6..d5b6e1903 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -6,11 +6,17 @@ source s_local { internal(); }; +source s_std{ + pipe("/dev/stdout"); + pipe("/dev/stderr"); +} + destination d_syslog_tcp { syslog("127.0.0.1" port(2011) transport("tcp")); }; log { source(s_local); + source(s_std); destination(d_syslog_tcp); }; \ No newline at end of file From 271259ecd98fcd6b4c57201189a597550fb2fc58 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Apr 2024 04:55:16 +0000 Subject: [PATCH 0357/1116] [CI Pipeline] Released Snapshot version: 5.28.126-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bc14afc5a..c39cef5d0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.uid2 uid2-operator - 5.28.124-SNAPSHOT + 5.28.126-SNAPSHOT UTF-8 From 2763e3008d4beb3e598806f5b40ccc14daa84461 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Wed, 17 Apr 2024 15:28:30 +1000 Subject: [PATCH 0358/1116] Change path to output log --- scripts/aws/syslog-ng/syslog-ng-client.conf | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index d5b6e1903..1a64c94c7 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -7,9 +7,8 @@ source s_local { }; source s_std{ - pipe("/dev/stdout"); - pipe("/dev/stderr"); -} + pipe("/dev/nitro_enclaves"); +}; destination d_syslog_tcp { syslog("127.0.0.1" port(2011) transport("tcp")); From f16127a3cff0e46b4377c7dd99719d0daf75a829 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 17 Apr 2024 05:29:21 +0000 Subject: [PATCH 0359/1116] [CI Pipeline] Released Snapshot version: 5.28.128-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c39cef5d0..a7c37be8e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.uid2 uid2-operator - 5.28.126-SNAPSHOT + 5.28.128-SNAPSHOT UTF-8 From 0ecc5715e60de9d0414e93f182c4a45da9242e08 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 10:38:44 +1000 Subject: [PATCH 0360/1116] Pipe start to file --- scripts/aws/entrypoint.sh | 2 +- scripts/aws/syslog-ng/syslog-ng-client.conf | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index d5411a981..868ffe550 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -118,4 +118,4 @@ java \ -Dvertx-config-path="${FINAL_CONFIG}" \ ${SETUP_LOKI_LINE} \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ - -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar + -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar > /home/start.txt 2>&1 diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 1a64c94c7..2588203c4 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -6,16 +6,21 @@ source s_local { internal(); }; -source s_std{ +source s_dev_nitro { pipe("/dev/nitro_enclaves"); }; +source s_startup_file { + file("/home/start.txt"); +}; + destination d_syslog_tcp { syslog("127.0.0.1" port(2011) transport("tcp")); }; log { source(s_local); - source(s_std); + source(s_dev_nitro); + source(s_startup_file); destination(d_syslog_tcp); }; \ No newline at end of file From e59fae9c7846777402fb82f96b1fd1500d9770cf Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 18 Apr 2024 00:39:34 +0000 Subject: [PATCH 0361/1116] [CI Pipeline] Released Snapshot version: 5.28.130-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a7c37be8e..c96656d2c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.uid2 uid2-operator - 5.28.128-SNAPSHOT + 5.28.130-SNAPSHOT UTF-8 From e24812f674da11641f480c8f71fc0e4fe69805f3 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 11:30:28 +1000 Subject: [PATCH 0362/1116] Removing loki configuration --- .../workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- pom.xml | 3 ++- scripts/aws/conf/{logback.loki.xml => logback.xml} | 0 scripts/aws/entrypoint.sh | 11 ++--------- scripts/aws/syslog-ng/syslog-ng-client.conf | 2 +- scripts/aws/syslog-ng/syslog-ng-server.conf | 2 +- 6 files changed, 8 insertions(+), 14 deletions(-) rename scripts/aws/conf/{logback.loki.xml => logback.xml} (100%) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index dc7d2fba2..cbd9e559c 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,7 +115,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -129,7 +129,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid diff --git a/pom.xml b/pom.xml index c721654d7..8564b85fb 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.uid2 diff --git a/scripts/aws/conf/logback.loki.xml b/scripts/aws/conf/logback.xml similarity index 100% rename from scripts/aws/conf/logback.loki.xml rename to scripts/aws/conf/logback.xml diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 868ffe550..132abd249 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -95,14 +95,6 @@ fi cat "${FINAL_CONFIG}" -# -- setup loki -echo "Setting up Loki..." -[[ "$(get_config_value 'loki_enabled')" == "true" ]] \ - && SETUP_LOKI_LINE="-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dlogback.configurationFile=./conf/logback.loki.xml" \ - || SETUP_LOKI_LINE="" - -echo "Final loki config:${SETUP_LOKI_LINE}" - HOSTNAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/local-hostname) echo "HOSTNAME=${HOSTNAME}" @@ -116,6 +108,7 @@ java \ -Djava.security.egd=file:/dev/./urandom \ -Djava.library.path=/app/lib \ -Dvertx-config-path="${FINAL_CONFIG}" \ - ${SETUP_LOKI_LINE} \ + -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory \ + -Dlogback.configurationFile=./conf/logback.xml" \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar > /home/start.txt 2>&1 diff --git a/scripts/aws/syslog-ng/syslog-ng-client.conf b/scripts/aws/syslog-ng/syslog-ng-client.conf index 2588203c4..7f69f0e46 100644 --- a/scripts/aws/syslog-ng/syslog-ng-client.conf +++ b/scripts/aws/syslog-ng/syslog-ng-client.conf @@ -23,4 +23,4 @@ log { source(s_dev_nitro); source(s_startup_file); destination(d_syslog_tcp); -}; \ No newline at end of file +}; diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index 88a50a0af..927e302db 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -31,4 +31,4 @@ log { source(s_local); source(s_network); destination(d_local); -}; \ No newline at end of file +}; From bddab7506f02bc06906937245de7cac724faf64c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 11:34:22 +1000 Subject: [PATCH 0363/1116] Updated logback config --- scripts/aws/conf/logback.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/conf/logback.xml b/scripts/aws/conf/logback.xml index 6d6eb0d29..346a52afc 100644 --- a/scripts/aws/conf/logback.xml +++ b/scripts/aws/conf/logback.xml @@ -13,4 +13,4 @@ - \ No newline at end of file + From 70234706b4abf9d6c7926af4d05bfebdd704f57b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 11:35:42 +1000 Subject: [PATCH 0364/1116] Use branch for build action --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index cbd9e559c..dc7d2fba2 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,7 +115,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -129,7 +129,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 3bc8436a223dad80ab83d6bc8e62edb21a5a248e Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 18 Apr 2024 01:36:50 +0000 Subject: [PATCH 0365/1116] [CI Pipeline] Released Snapshot version: 5.28.135-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8564b85fb..acac769ed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.130-SNAPSHOT + 5.28.135-SNAPSHOT UTF-8 From 25f78797ef02541dc5b74579b737a41b1130db4d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 12:39:32 +1000 Subject: [PATCH 0366/1116] Changed file names for logback.xml --- Makefile.nitro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.nitro b/Makefile.nitro index b25d0afba..0fb257bc4 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -37,7 +37,7 @@ build/make_config.py: ./scripts/aws/make_config.py .PHONY: build_configs -build_configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.loki.xml +build_configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.xml build/conf/default-config.json: build_artifacts ./scripts/aws/conf/default-config.json cp ./scripts/aws/conf/default-config.json ./build/conf/ @@ -54,8 +54,8 @@ build/conf/integ-uid2-config.json: build_artifacts ./scripts/aws/conf/integ-uid2 build/conf/integ-euid-config.json: build_artifacts ./scripts/aws/conf/integ-euid-config.json cp ./scripts/aws/conf/integ-euid-config.json ./build/conf/ -build/conf/logback.loki.xml: build_artifacts ./scripts/aws/conf/logback.loki.xml - cp ./scripts/aws/conf/logback.loki.xml ./build/conf/ +build/conf/logback.xml: build_artifacts ./scripts/aws/conf/logback.xml + cp ./scripts/aws/conf/logback.xml ./build/conf/ build/Dockerfile: build_artifacts ./scripts/aws/Dockerfile cp ./scripts/aws/Dockerfile ./build/ From 76912536a2595f4a3545b0bcba31431470663ac2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 18 Apr 2024 02:40:40 +0000 Subject: [PATCH 0367/1116] [CI Pipeline] Released Snapshot version: 5.28.137-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index acac769ed..3e742e26b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.135-SNAPSHOT + 5.28.137-SNAPSHOT UTF-8 From 41b745f98a6d04f7e8a7cd8928950d9aa5af1dbd Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Thu, 18 Apr 2024 14:09:32 +1000 Subject: [PATCH 0368/1116] Set core and optout base url based on var.uid_deployment_env (#504) --- scripts/gcp-oidc/terraform/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gcp-oidc/terraform/main.tf b/scripts/gcp-oidc/terraform/main.tf index c32d6eb77..aefb68362 100644 --- a/scripts/gcp-oidc/terraform/main.tf +++ b/scripts/gcp-oidc/terraform/main.tf @@ -108,8 +108,8 @@ resource "google_compute_instance_template" "uid_operator" { tee-restart-policy = "Never" tee-env-DEPLOYMENT_ENVIRONMENT = var.uid_deployment_env tee-env-API_TOKEN_SECRET_NAME = module.secret-manager.secret_versions[0] - tee-env-CORE_BASE_URL = var.debug_mode ? "https://core-integ.uidapi.com" : "https://core-prod.uidapi.com" - tee-env-OPTOUT_BASE_URL = var.debug_mode ? "https://optout-integ.uidapi.com" : "https://optout-prod.uidapi.com" + tee-env-CORE_BASE_URL = var.uid_deployment_env == "integ" ? "https://core-integ.uidapi.com" : "https://core-prod.uidapi.com" + tee-env-OPTOUT_BASE_URL = var.uid_deployment_env == "integ" ? "https://optout-integ.uidapi.com" : "https://optout-prod.uidapi.com" } network_interface { From 454e17183d845fe7ea36c370c433167ca447c69a Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 14:39:33 +1000 Subject: [PATCH 0369/1116] Removed extra character --- scripts/aws/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 132abd249..73f5debae 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -109,6 +109,6 @@ java \ -Djava.library.path=/app/lib \ -Dvertx-config-path="${FINAL_CONFIG}" \ -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory \ - -Dlogback.configurationFile=./conf/logback.xml" \ + -Dlogback.configurationFile=./conf/logback.xml \ -Dhttp_proxy=socks5://127.0.0.1:3305 \ -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar > /home/start.txt 2>&1 From 128508a0740c8825b882da47058a5e1869719a86 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 18 Apr 2024 04:40:31 +0000 Subject: [PATCH 0370/1116] [CI Pipeline] Released Snapshot version: 5.28.139-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3e742e26b..6988d8cb1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.137-SNAPSHOT + 5.28.139-SNAPSHOT UTF-8 From 50fd771458fd30085f762b58e5ac9318f81fe8eb Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 15:33:40 +1000 Subject: [PATCH 0371/1116] Remove start syslog-ng from startup script --- scripts/aws/start.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/aws/start.sh b/scripts/aws/start.sh index a55a8eef5..705acb80b 100644 --- a/scripts/aws/start.sh +++ b/scripts/aws/start.sh @@ -99,12 +99,6 @@ function run_enclave() { nitro-cli run-enclave --eif-path $EIF_PATH --memory $MEMORY_MB --cpu-count $CPU_COUNT --enclave-cid $CID --enclave-name uid2operator } -function run_syslog_ng() { - echo "starting syslog-ng..." - /usr/sbin/syslog-ng --verbose -} - -run_syslog_ng terminate_old_enclave config_aws read_allocation From 1323d140c5e8ba9612f1563c555711aac9db06f1 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Apr 2024 16:35:00 +1000 Subject: [PATCH 0372/1116] Added links to syslog-ng docs --- scripts/aws/syslog-ng/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 scripts/aws/syslog-ng/README.md diff --git a/scripts/aws/syslog-ng/README.md b/scripts/aws/syslog-ng/README.md new file mode 100644 index 000000000..5631e7bdb --- /dev/null +++ b/scripts/aws/syslog-ng/README.md @@ -0,0 +1,5 @@ +# syslog-ng Documentation + +The documentation for configuring syslog-ng can be found here: [syslog-ng Administration Guide](https://support.oneidentity.com/technical-documents/syslog-ng-open-source-edition/3.38/administration-guide) + +The source repo is here: [syslog-ng](https://github.com/syslog-ng/syslog-ng) \ No newline at end of file From 55ae569ca955c7e9d4385b790d8b11ca3af324cd Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 19 Apr 2024 14:55:39 +1000 Subject: [PATCH 0373/1116] Removed requirement to use 3rd party package repo --- .github/actions/build_aws_eif/action.yaml | 2 + scripts/aws/Dockerfile | 16 +++--- .../client/syslog-ng-core_4.6.0-1_amd64.deb | Bin 0 -> 744720 bytes .../syslog-ng/client/syslog-ng-ose-pub.asc | 53 ++++++++++++++++++ .../server/syslog-ng-4.6.0-1.el7.x86_64.rpm | Bin 0 -> 1025776 bytes .../aws/syslog-ng/server/syslog-ng-pubkey.gpg | 19 +++++++ 6 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb create mode 100644 scripts/aws/syslog-ng/client/syslog-ng-ose-pub.asc create mode 100644 scripts/aws/syslog-ng/server/syslog-ng-4.6.0-1.el7.x86_64.rpm create mode 100644 scripts/aws/syslog-ng/server/syslog-ng-pubkey.gpg diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 3a81d9dce..1610e7032 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -66,6 +66,8 @@ runs: cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/VERSION cp ./scripts/aws/syslog-ng/syslog-ng-server.conf ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server/syslog-ng-pubkey.gpg ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server/syslog-ng-4.6.0-1.el7.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index e2a25cc32..2508d9c9f 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -14,13 +14,15 @@ ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} ENV ENCLAVE_ENVIRONMENT="aws-nitro" ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" +COPY ./syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ +COPY ./syslog-ng/client/syslog-ng-ose-pub.asc /app/dep/ + RUN apt update -y \ - && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip \ - && curl https://ose-repo.syslog-ng.com/apt/syslog-ng-ose-pub.asc | apt-key add - \ - && echo "deb https://ose-repo.syslog-ng.com/apt/ stable debian-bullseye" | tee -a /etc/apt/sources.list.d/syslog-ng-ose.list \ - && apt update -y \ - && apt install -y syslog-ng-core=4.6.0-1 \ - && rm -rf /var/lib/apt/lists/* + && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ + && apt-key add /app/dep/syslog-ng-ose-pub.asc \ + && apt-get install /app/dep/syslog-ng-core_4.6.0-1_amd64.deb \ + && rm -rf /var/lib/apt/lists/* \ + && apt-key del 6694369F RUN pip3 install boto3==1.16.9 COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar @@ -37,7 +39,7 @@ COPY ./conf/integ-uid2-config.json /app/conf/ COPY ./conf/prod-euid-config.json /app/conf/ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ -COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf +COPY ./syslog-ng/syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh diff --git a/scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb b/scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb new file mode 100644 index 0000000000000000000000000000000000000000..0da73f3a273cdf8853f13b26313f022d6c0c4690 GIT binary patch literal 744720 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�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 z zmL_d&LODgHe+#^~?SZ55iV6&-rD$OpP>S#_ZWGW-O9nesm8AiiB^p*(1R^ zdN&&|pK7*msn`wfn2Jn*a(b??>w?W zWN+4xuS#bhndFxPkp%(!1yR&R^4gdO-(o_qfOk0!)`rGQ~3>8>N!^>K+^ef!Nt1l8kM zt)hT4kzg^5nH%mvaAo(8ZsC_;dvQNN?J?X#!DmTDoHYq*X>`%T^uwHW67MJb)L~~V zY6FvDBBNjfo#vl4Jgg!n%cQ)n;HDyB^WWH*tPh5Pd*Izik+7w$#+6`U$6w{Mb!Xa$ z&OpOA_j@HoHm8e>RYW}dZEn}RosRuAZ(=diUBou-iB4G0tbcZ$=XjJsv6?1@+XlCz z@$SacMue+ex2+HyX=*&G62Si(-!XMn6BX_kcxhYOToSi-Nkrlu^bu`I379NEVSJT+ z+;HX(M9uqwg!$B?fH!(PPF}(~S-OdzWx2SYYJ3?fL<{~H6oT43DT=L&3%99Y{~WsV zcsK3$4eYG5dCHez1jx_GUm$_oA%ilBr1&+F9IDjuHSi<%s!Nm*aQ#FiDvI=J@*KYM z1=&0oPw@~)^W4=g7LZI_YTYV98OR5GD&`!3M`Ab5VMXrjNY<-0aa(lx zmet3?&f|TfxfwSrpHh?4*t7{DkjrU&(h1KHekbwl<*!5*Dz% zXiud^dG8VbNMYA2<`~bl5r!`RW(GmF5{q2m#_!#3DG<3SlnITDKi4XUZSE}^l6QDB zOB@?_B~WV@BI;#U=7QrcXGw&On~Nn5A|gsRatHnS^sYAwrf)}b{gbW4R*?!N$Oq$<5yHbDAKWoAk6m99D$ylQ? zA0M$LG5tR}Z^yUyYn4x8s6BvOydF>kfzI>8;aj(!?}c!oK>4h$rjZ+IR@IUp7?C;Y zFl`b+N-nGiV;CkThZq1o z7*W54IA#!+j|K+|9(Jh;nak$i{sX(8F9n~5&K{LAKey@3^EH(g-jus>CtM%V#8VF} zC5DtC__OBBg2}LM@(FYp&Onpu^y*pm8HJtSDVSMqze06Q9{{CU-;do<(UhZ5RzGx( zcZ&QE%1gb^+nwD|2~rYM0Ky?mBM$fRD6EghRj^HyEL6&^<})iv$oxN2f^qxlHl-rj zkI(*9lHm;1Uqx=b8a(^5F_MbX8F7+b`bH)E5Swl2VawQH0vV8gdj^`$bGlC(z~P8} z-@#YGPqJiYFtqh9@vW)4vS08}nLVU^?NYtqv-I21d(!MVUE5ij z(7n)o`n8A+U8P7Q!!5rpIQtP^AInw?`#Bd$DW!ai+x`>~sL?0-7(#IGbvvn)T>s{a z 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

;GYp&M6Ki;$#oAw!Mgnn)_DR@2 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‹j3^B#)<$MesndlCoN!I$U}tgNbbn2zqmPK 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�r))dmP$WVlm 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

J3V=Cs&dYVA*WseuiA6%C7T z4qMaBDjg!d+ZBvS2+-Wi^%Dj&r7K->yN*{S-k2E00B%6LAG(KE$06jv#S%Y})Hr0) z(nx_)ZcW|Hs{nn&UyO|Q6?=$_({N<+PawW&=os~pwSn@`;Jjl#7RjuCWc;C)(CA{7 z;taf^YVq+^D>#$cgf4nZ<9(D;sbE1Y5-tqfS>#_sqq6lfmUNuLd#z+WFS|4)QT+gu zfqUE^b@knF18H53HNlD63lO7u{ntsP&WGyfM%YPpnRn2dbY?xQDVSSH>RHJ1@u}}t zv?*tTd`U^$+G()~5Q|=|)ua%lFfmZjtS88!daxfR(aswf<6zS^7-r6dPg}4l3fl4C zTe(6CFa3d@dIu+6FxFgU@wSFy+UhfVf|prG;8Owx9=RERXO_AFEOeou&9*=g1DGgi zP9Wv63{MA)OAWB}4V@z?+8k_{^}bQUfm(R8kC#0JZ2@hqQ>APXbI>UtYYj90m-5}+ zLr>BZ8Q|udQg+hLdzT%} zu+@EN;-W8t+aY$;A7zDDz=m5N0O;^C(v%MJaaD97-|9WEXzs-~A7$@ZkCx1(Kd0|5 z@$D4j_~YNNRc@uD(FZS^jfs z5+>*@_+5E{{p{9b#?!1K#XS(P`w^Z@^n0!3ft@pylrFy@ZF3>MJz?Fk+d{@w>0j=k zzA7>ldjK<8ND0VvyNqp;K%bG6$9jYKtX@m~%89u+o`Mu9^9uP{hL>?Pj6c7RoS5QJ zl6hxRuHNMtLv%loJm2_*Zd$;|F!O$v_79mrOZaojHd(nz#cz98oPPAE@6p;*KUdGl z4j4pXsf%L)IuY+{mhV5Uh`U&Mk8fbYx%aP%kt z1@ydvUq?Qj!uYBElNVUDJhL6b89AQoTai<@elrAaNHxrwasUhtm=WF|dN$4c%&q6@ zM%6t2?4X9v?I!!r_1hZlS7V_rRJWzQ)ojM5ITQ%kADrn~aC9&97w#q`-bn0H_P@kV zu34ph5rBzs{d^X>aa@vC;MCo-z_2k zh+Jp{|2y?eV7|e#w$aQUFAAjYsec>W>2ME(MWxp#I40GHiemahr;adSE(#y*6~0?6 zZ=kav@3SoETyvZtKo_csRLPMuR6!zelWpge_+C}9g95${Vb1n5u`?$ya zy+I+8n~FGFaW1v{d%;$y9VwA-k)(~c;=|Jb zdrs2VshP=}G;U zj*^)C%H8H15>cBtIq!5WII?{3+~Uj&^BdgMXt=IIvVGoiS7XOUd$$Y*&(pSN5)4Ra zL5Z0aR5=$yH-RS=?E)U*HQn!)^6?pJ(go-LlDNaVs4+#Y+@b)*7TlL_Ko*Q^qNj zGD_e}w$|>~pj!2Bzn3e%)?(4DKl<&)8{!#7*+$i>4%|&m*m3g^mGW?Zc0%BX39<2N z{*4nO#b!!nGRfCYxs-vI7_vOj4C2SZ_PPSa9@%7VyHDSZT7)&Xz&)YL(xU(X z20*szbeDBS=!h~9Aj3a>v7m6Q-VnPG5Y+y zgQUeHLuk`bbs`MX58PMwko1It9pfVY(bHi%TvOxv`2f0siiJ(-Erq%?{XR{PWQg{$ z&(; zDO#t%9PDab2V$8a8NdS{X4Ym|KmTYWO@!-7(~IvjVL+CAp6HBe%jUg|p&8{$9Dpud zbInDy+}=U%EtF)m>lbll5vbt%FGoqxc*M_4Zc^@w_|%tb%HNgUTK=a*#bvin1;5=z zseXUhUsjZ~;uEYL2rAG5uPE6Qz_o3Mwc%G+&;0d}#2YM+BPm_bBMNQ5vgXXx(`sAb ze4x@@hy$bFj-=^Gi0pyo5-ecQCwP~2fH0f511N>c#XCwrzgJJ;{MIlNRUw$P9+QWP z$~T8Yn|BIM{Dh+3z*!cbU0rxF^#Oh9wj{1GcUNghyRM1sJ<>^ra>4G;XqG7yK9r}3 zLJHka7aCDU9-R3Yz*hO{8{=;nX_F0EBmnuwb*@w}idM9ja_Koi0HnMx0L}Cpe1(8~ zAjs0SXG0B0sHdiY~1T;Q@GL%6S zvDDZ+fcBxEW4JUlJC7Ak6X?Pud%A`f_@Nijn@;bs0ZnCtV7&&$I;D0*);}G(?8^j^hZ^y+)zU1|wUj)r z@m8si^31w=L>~{_4qLuek?EIfmzoTE9@$iqxC4A>Ekg3_SYY!^WFb6cA!(XEXYaV z)gpF}bTjot1Pkzl4nnJPi8`H}d3()+x)}`d^S`-rJG8iqO+N3HL5p)hMZNE_26Mq^ zi1O434~LsK3x&f_#$n7poSXw=R+lafxt)AY+hI)a3L@}F#%l{Vrm-ek5E@A7RVC0z#<>fBu4H+@+s#O z#g1AVF|6<|g&UFjpvoD*icnRX9ciH+rYx+r%>?ol^EJ3srl^!E84|=1= z$Fb}g1W11Lr~hrvO*Oj#e9ZKrX6Joyyq*{&*^kc%n|l*U9YTy?j`JP-G2hRXHt`Qx z4I3OFi)3)51%m~gJkCRK0-b4~hzW{8k66+hC;RGje*bF82PaYsQupqDfx z*>9Kap9$AFF%W}9c{!8{kqMXK@=s`ozZLIjPkrh=G_*`3)MWfqTmCGU-$DMRmCBA5~7zg|ftKez+PYK5MsZL*EW^Lo)yZf+zIH=-KrK;ltW3}HqF`Mikf>ErgS!L8 z*wYc&-lR2bQYv))sLfdq*7oK3s{36W4znScC#iGT+HZyqIqK|rL0$WPT8)dEW3CjR zp$4X{6MGQvET<4>8da=$F_p{{&{Tp6aLX2L&cEp_IOdR z7=c3`9 zr-$rLK;E+(@QpEk?OgYY&=Cb%jV99_JVj)av&q~f!dLJ>Cd)SX+xJ>&M-WE#T~Av~ zxY0aCVW!?Ex;ZFAMcJ*p0XMrp(0jWLUd7-x8GEINjN`cXbj%V!dYs9+?e?Nh`b{sb z8mT_OoNKw@lSm=)$P$=wyZ|GI3QY)`mlXibYjUO^tVB(@02*#fS*hq~({CFzgXn_5 zk$Lq4!T-{f?|9&7m28(moxb3x%`&Ji&5+0f*p=G!gvQ_Ir8Q5j;MY;ABe0tYH?bRg zD>*^XE%1V!*5E;WW&p?+o<9sQH+$J}98(-t?}#=470sv!17wymLdkAI2dd0O%P%2E zgWgD&g5OcldFh8>L~;mGr_h_lAP_kmv+`=8yRvfC+Tf*yo7m7o77B6fHs@RX+r1*| zwuj%FvLUB-XLWPH-Qon4`d7g&JPe4yz*41h%>bv?XVmruiSvM|K=ma$*H*mX+%kg< zFd@HnbpwrG>*BNbxh#_E@2R=qD<8sb_=F2;J_jmLzc6$~MZZORnd%~*Fm#I3Fql_3#Wev+jkO?}lEoX)o3yd2%?$j|`{|nrfL&k|x?yzA zMVYA*YeiryVUSP`BLX$j#6QQ7i)l5K*I5=#aXIVVQ?N9lXBQJjg(mD{iXEDlW)y>A zF<4X!u+GEsVz*`G#xowBa5IE7IpZa=I>Y6m18zisn>8z4pcKeZ8dIkt zhG(IMs&E=UlLu)~gsm@U&ucx`n?NBu!@#L~nEW|>1+YUpsv^IqITdI%AsdLw z|Jfnk*%G%}j4sSLRu= z4!WjyAZPM0Os4sYhGB#K|F*bflx$-zpuJ0jUX|cUfwx|!u{bo-6w3GdQ8CT=auaS7 zNR_JR^fT%nA>^G$RdRzsij#MGpnt$j4=|0#hix31jW__uZX^rkt!vHkTK_n7Q{ugw zbHMdQVPQ)efbZOO(e^hQ5iqI^sA9EX3S_4}S5XGjF>F{ckUpgAI0UYXy0?W8xUv@%K8&ak-mT$qA>Curf(~f0 zfeIF9v!;eiG3`>}JNRURR4wBOr&0PJcch0X9{YcoY_ZcmX=ciqS7T=6vlxfklqnE5 znJ(d%JO1LIdnSmUTb!Fku65-Mmo0&OVd`-$o{-kT0=bZuA9T4`% zHS7Q;{Rq?EAJu{zAGmHAY8C9wzPF1_!B~EZKr9cUkxeMRAsH#bnnBP)8s~uo39q6` z89sYJ*CuLcghz8!pn*P&9d!eN497%&-4$J~e;kaxLA4nbOWK<2?eW=d2KKN?l>gfc zaoo@32%T=)KYrb-T@E)8-aWcefP2s;#=`RA{_Qy8nSdAHBH4DtR zkGMato(S+bh`B_TzAJZ0GX5e$J|C5_KN3%+>>Rv0RB}t+|}0+1b_L7 z6n0KqdxOw&#)dIKgr&;X&qD2*O@kiaT$zS7M~{SNNiG>cCRkw4XXqARvQWjAXI#8qG{VvHPBy=Vp>rB!50p!RrZy=9LOG8A{Wl1Y6y}}tuLNP_l zS7#Il^*L-AZHO5C~J9bkA_WB?po+qUk6i0HR+=BUBUVmj=j9v=QF zr+F{*4fe1OrGN#8@&D}7(4YwK-M-&A9zYZhtwK%Rb<)C{=av5N54hMmo1z%l1_d)F z$1fIt^)O;~eszYq*vcM=dmgc)`_-%0feJNlA=Yka@DvneV_%{B!+#EoBZ69*G{_qH zhbKE_@=3+)+kgUQ-%#)6DoVk4;|L++JtpU*LCq$Hf#8hisxA^lkG|OTQj)tp8y3rT zHt`UQtDmU!vE-+u(5h5H(aQOlo7&6tAI0^kIe!5Y4=lguSIf5@v>z!0PYNk;+cRfS z?tb#nHapGgh+jZS!+|NXA4oNW%z)XlTPrvzc`l|~!wFguyC@5WPv$m)Qg7h~jI{L# zG$`?J(z%fo9aj7fs}#juBNc8Z?=h4uhk%T>UQ=F}l@=B40?dwpe!=i36E1|FgHF)g zL>!2NZ1q= zLE%IeghW+H`l&F-R3qlQe-`h%cG{Z*i4pD=PzfKASYwx6y*=N==A?Jz z|M}-F8WLA5d1LjXZXCHZ$BxB>+v8uR!`Ym1LI~GXBo$?dzXq(jo)#12ETBs&dlM0G zuXx}fK|^(W#G^Z?&lMk^zKm)L^n23Or12vfpPzK#afKJoM~v10oW6bmKX7xDo;AvZ zqnHU8Fx|KS`m+)WXo2%9H*__K?f>GXK$i~eX(e1K-X$^NNgAsv-Jn}f7C^rQ{IN51U9>8|(IG3em9T}RFiyJMG`(Q) z%A%eCm=mgjj~N8C0Tp^BT$#%|QNA4y%lxT;PdV@u*6P^ZMAuv)Sud-(4&?`771y|L z)s#(9Zt$npF9FF|RY2-er`$QvMj#p8w#07HW2(d^{7L~dWVri{d_-sn2=OFF-lyit84H1in_hJRx`sP2cGux%l#4`_Hs z^5D?bTnSf8$;M$POllPmn)Fk5wB*@f8HaqLjc$863mXsak;giwjQmP;tS79(D(zg` zs0t^oO_(1vE#`fxuceCHB?7iARFw*V!+05N{BYvF@fLprIispI6jvM;8gOdvDi?Oy zSm*e31IV}S4y@}>2?}o4$%kb^F>fg^$ z0yj0Xv2x!i`pzekoGf+z{(yuk6L50dbJDsYR1G2d#$f}^L<%XzN9(E z%bc$BA9(oZ3MzvM2Z{KYmIF_DKx^GY85lzm17)c1*K?3oC{Em|F=AY|h=tq>J(7%ho<_eJm zaSDGH)Ps>?MTPdZ&LoYmi7OKMy4~B81!9k7l}UrH7r*HA@?yjV zvC&tDeZp+H5*WYHoy1K^85>__uAnExl-rR}F2HQU7Qae{q90z&hY$r<-vXzJTfYuH zqnymFe1|SJ0hpSVN!!+N#WoTtL%m_;kjiLLgoj`7it$X@I{A(Y6SWVzgAI^o7``Tf z$s)RiK9s%~xX{bFu-qqQsCAE3*|?UYoL^$j_{RbGZw=k?AdQh%lLqRpintEB%>jVn zZhf^G-{X;QXj0T%st8rht2Wc{rqzoo5WxDq*OsI@$@7NE~nK~ z|40}FCdZQ2F59_Yy|9>D#=mnt)8AHwzPu)*Q{bl$l?E>AnY8;uQH&+_si(vjseOC^ zzR7I*m*KvL^e-OH?V=I=T4{$tQr_Gn*F&AN{kvwZq2yg`_c*Lf_0PaC1qEnH(j=4% zaK*QtPvJTa9@}8cwKFj@a3rt950Z%>C?mv7Y`qc>{2iOhp&w<=7oJA^^9$QIs9qZkJC-} ze`oEL`+$^#SwCyOy$K@WR@?38 z9`d6+>nG(dlql9)KphC9;>9ZjL!$nJy+0}Y+a8o zoEM&>S@+LcYu?69@zHdjfJ|Hd=fgvCUlkCP&`ftFBgTrY!TPZ{*Cr_u(sRB}(=DtC z=?@#0t389A1A;9Lq3wLd}RSt!8O7xw>2MUMo2#ZF1v5ojTxR=&u;pRP$z2x3J zz==cZkbXBh9+@*~MCgimEP8kL^IVX!H^(7&1pJzb+rFcl8i*9A6=ls&vjaM(F>M^W ztCSbR<3D{xMa74s#HpPipHXJW?taW^XV7RZ*0~N7a8?y!OS};f{l|9=U)~Ky^j3cz z;(AnTu**hb78aO04oaP6MF2NI$iG4WN;MF%^cXTrd(zx<7*X%Nj8l@C+BQK#0ik-Vk%__G>Kgq8b(fR%Ly{lS2}#fudz0n72SN8M zhF_-tdWoh#F_moH;n?E++Obm4^Ob)y$G(BzE5dwHybN=oYWz|6)xCh6*m+wKecdRL zYlI$qVsTb5Q3tU)l;yv9si#+Fv&h`_R8Z(r@p?a8efobOm}tC;l7vxJR}a3yQfj(|OPMe)t%3EUibpN*^;OiX2IgXu=)w5^ZY3#{J6pBuZu?(YWlx`JI~xQ0;8?qs zU}?QcPRDrnRZ1pH#v6j@haNByt4ojDep<^po4h3@t)eAY$@v+0sJzbjW>qV)s`2Ql$Ur=7bQET^RKKeKqU#?L9OE1RuqlpSB!lB?Ze`lk zz#fYQgJI%XOzweGs=yOE<2N6mIV3;r{z00T*!dHT z1df!@Px4k^tqr^-C$OFdZdq-XZMCyEiC*j>p55QZC6L5J`>4S$eX%DtfXG|t!3xY* z3)uVJQPxpVjFB?@1UjEEh_?1O`eBy&0QkYgPeC!g^I<75dvonMD13JM$*Cbz+bfmg z03`aPN!SeHD6VDdTQ9K?LB@d_a0>$9&t-Ep3&tieVz8Z7#a>~Ui1ATtO`9^?7IB9Hi?+_) zojmS^F$Dqq_3xz9grE5p;=2oS5R#Y%U$zjL-B>2wKY69B*Dj;79IvJSOj~6?lH;iV!{mCwqkY}>XLnTNL%EKuRZOKs+xb+6D z=soarKc|!+!`I^g(GylZSMMHD913)kzIIrj>jA6C{4qyT~U;f zdA_Wl(=3$Tj`iZMt{7pS2UFKivsO(sLDzq{~$ zsn_AZB%jmURjma%*=jw{kxd%mVi&={8=>ey93YB=BR9tEX|awMs_`7fK_fIbj3F+X z6?TzEon(XhNA#6hLm^8IgiUqu`*2AXkR<>n2cpuBktpL)d_I(0EW1*oh`0IKt zg|$070L_rV(LEEvY&f?y-wisDDinhZ_rB#6yO7qSz`#3W%u$A!iy9N~In08HD?)kgUez6fRUdutCL3O z{fIEn?`gKpN8EaY|AripaIM?kzF3Y)K=j;U!Iz8CCe=ZVcZA16>;S{osxjqMC&WxviH!p zFYY!97%u%TB`|BPSuot{yg*d*<73P*ys|+Xjuz^6sYPgVqELhDsv~2^a#d`O z1>j-KKS|dWxXMPVNQ|%E`rJ2kohmRa9pv9#lEMSPFO0XTwM76Le1F*6Ns|IWQ@!|@ z6O9z$N}zfnj6g1g9z$Yr_6Q#TKP1W|nc1g{8DUz_ z`-$FqtF!-K1>DR#SC$H*{(5~JE@_kzK3()ks0shlJ5bDCNh4+3?yca@-Bh);J`+@2 zNRSbTik{;2dNaU$SeJ*UMYW$g+R?U!?s@e|(5s2;n^^yJREUk~kj1_*+s)1_(N zeIFOFs28#mpg~UsY0-v#&x$sE^;k1C0GO-Bp{NN9*w6iF8}@~);0W5ak5np>|9I8n z$Cy1Kb3-~-r!s?8rALMnt|u;sU!q4DnX2DIs2+`$GMo;posP4|2^|Dv?MENxhQ!w< z6K|h4EkBgEfu^3~2><0{aZl+K=nZa@pJbZd7tE%jwwF>8F+IeX4i5uI<7$&-5#kJK z<`1#1Ueh}@^DtlPnMjU$1Dv95(x|A$2_Qqc0cBd+RtyL6cPf^r;+G@`J_Gu_c!5+? zY$ZnbK2D8azg8e@^7Ev&;;Y&zXD@Xvt32g+iBWfLzzV&A$M4kVxvlz6hCFyGs1O7w z%1T0g(42e*ocr1Me3=dNI1V>e9j&-;UI`YK3 zSW<-9rCVfRd#Y4lBr8?K&G*6jJ~!t=^iGi3V}9D2ZD{__+djqRuDq5 zSN>b$reiIE#RyK-9V(^55Zhi3$Y_LXi$9P8FZl+4L`GiIQp8eiH3mEk&rD+)XM;<2 zKEsH;d|hERURd#|kny82N17>gk7az|iI;x@kPDEl&0`$Fjww*vq(XEYMCB-;E~HvT zc?FxfQuQf6n28c`x8?1;)L5I{SCH>3=u-3-#e4l$)jg+#It(mO9_}x;5@7 z+Gpt=y!{o8z zMm(3*A4fNevx9vYG&@%%5CHR=6CH~jFdgU2LFT>-2$<0za5d zw!a$vV0F^#arIVw!%eQ#M1r)eAEW$2N(d;qM2;R^q@3zh`wBmM2ppx3|AvA1gJ$`$eHlvc@rzULX#=h%>(ksoiRrVuNJNLSKP=CBac?wkt;0!Jt9B-ji#BEEct01gKhAn)H6@l|t4pp(lgn`-w zgMP02yBHImIuxi|A4DdoPoJPZXC)N#T|-!1-$z=j_&?@FcL+|FDnXv|_m2)%r2kX& zi=O_QMs=#~{>@y*I&0ge!4)>sn~J1gGebXGwk$JAznA&1RU$RT#Fe>@#S?dh>^rIJ zB$WkvuEXbaucDZM1cw7nlApHf?uxpIvAg$M?ZQD8ecUxRX1Nl5&*sbNU!TAolowG?5T1L99EqFe!G;Z}w=C~DSuqoGbLWU|?Y40aA@2da z<=&}@95da?i^63~#0<1%u@ezQ{Uv0H)>fLwo4NVfL{&Z>ky~C2KsAty4#6cczk;^= zhlhYD3{9t#3m%0SOZgd1*}W;2Vt7WUxjJqawwx*KGRZeU0AepC+?w zx~sxXGBQ|IaNhY6C_JhNkDa1%lGG;#U8$wZNR}`CRC4JvN@4tAu0+vI8; z-{HZWrHXX|9X%s5jD3Z-HaGbd*l-=ts^SwOD$UaXaCyg$)qtU*%js<53@8l<)XSlkh8F) z0n{1Np^-L=K(z%16>pyE>lx%1NMdtTFZKe{516ciaF?5|2Ivj#mful3T20>rO;mTq zvyt>S06WVP5fF@v``QTLpM8~hW85#&$O(O!{J?)m0i|Khldx^|8r7s*!L$ZC(Y6`Q zm&|lHJpj z4T|EjyX=AN3JmnSxny;CEF3%#k#18D9pUV~T%c*$`(Pr2tNMv{5|n{o*`a{Ife?AI zkO~&f(f@*xA@B1)|TEHHy%Xk{4lDX2MuxtP2?{VGc@ z{3A86IvJ15)MyrT$xzx`>gmj$m#ZU^r4V5{kMk;H%G(_R#Uu`TlmV2tX&)xCRb%Rr5b7 zKvCH)4JPIzE)-hcY!zY7;G~35z_$26Su^Yo!Jr>Ab^8C0kYbic&eb><%AQoW$Fio_ z9~uXfta&wft=i32p}Jt08Z$>`tO*r_!0thG_A4LZqpTu8?ASH97sWUmHSBKkk@63e zggF}?b5)BAA!6E2ggDL7ABIv`bo1|pBif{zeCF%6u5yrEjr>*ui3bxV>W+?R1vTG< zxsRbnpd7Z5N{@{Uq*O+!#*iJt{xv(jiS zg8wn?5hgLHbV-)y@Cb_1Ka7T8#t?g=g4Ge`%*S!{d1Y}w_vz58!gvN_#Uf}6g|?%P z*cbP>mt*9SV*w3fq`D_+%f=QGsMPudInIOdEFY4`*JBVuOR~0W^ZJi0-`>Wh@t96;!juoIF4b5h2;N^q|NeS@OTo z^KDv*8|T`HYOYES!=qXLZRTT`SbmZl#-YpXebIdr3$Miwz0VlbL34okC0;butZ$k6 z7}@k@1GP-*TDeE`gSpaPSR|}z7xm;O@ceRhVDMKww(pX+7m!9#fVTMUCkQ+KNWT_7 zMmX7e8|Dc~ILYNH1+&tjHyEmG_HjYU8+f6G@?(Ok^X5B!GbON?S9{6~G47)EoNO~UuH;3q$(wk7fgW{k8obE1;>$E8?P5es>D?Dm0AwxC6@GVm0*zo) zcV;@xf>9u<*|A?w)@t;Mw6^7=ezci3_lQN!)uv1W%ho$CLHpOQGu55OCJnP1XYMoU zuV)+BIL5^_Yp&EX!I zDyD^Q2dlhA2uGHr6Xq%#5bTC{~$y-!~@|x;Zi(Z(j_HoGS z9Y@FdU!Ho~-DG!DpfW1LMo(5mWU#1%xa|Gexq;T7pPyyFmHHc+RUqI$qPUa)5z_CX zzLXsd`MI1{W%-jyVYng@Gg|v1XJX-EKM8=L3D4#Q`2L%dGYM;+dg`DG4BBL-+OL&E z*3_yU=1;M(V8}N8Y`Soj;FQYrIrS|Ntge<^_YLFMp~Y&YkOcKbdM0h&w;uHU<`D_5 z7u+8+&66ywLi0EYJXre9Dny^MG`5w#B1NuB#N>T{?rD^3^0tM>XlSz+pf5nib@6{A z3lK_YKS-J;&3kzx0BY%=d_!YEJ_PRQ3c3iA{~~&$Fb^kNqy}awLw78HNh4YSl9Z>0 zlSXa2Og&errm-Ot_u=d$`x<-{;S0^q^_Y7lW?r6p>r&Tg6J?L6E-?Ilxm0$oLn42^ zaL8V)@B)u4TPbMf88vB_@ZPFqP5-7};ztYFWh=4BMv%Lj9=VkOSpc(2zS!b6PP2>T zEw2Ss?j$erI{vAx5f7#~jkPyO-_36JvJh0|ue=!cX3f|tgco+2F~ z>z^~c5xV{ght$w;)ti1^+O3D8x!+rIhZNG6hv-xnErtZSHz+NoEg}-2TmtG43uPvg z7=w|ZHz(X_&fpVa0b;e{F0#KC3QI9RXLpYnbT6v1-+TkhQdIob;Nw#C<^k|0$tU?% zY_5y~PM@T8w92VHsB0hgrfX9Lme_Dttk)}!&vH&(1)eaPg{1D!c^J49#4Fdb7%&dk#m(ab( z=(bkMG_9S%a>OPv(7kt@jE6}N@79(4vV?KBN=4UjG+I3nsknxs4}D)BKwyGf@!;W~ zPIUjxeYC^svvzflivdcGKNNb^!q@wrKBqFQ?v<%Zn;>j$mULOXBTvx1PL`0D0lhww zfRs|k34Je9h7sM+TsU_qFdc`duU4G@7j6*@E`@ zY*;&NSLb(-Svw!%+}bS6#61RofsF+}E#28n$nP!0cO-ve@l()V7`q7I@sF^bpFJ(K zL5J<@nYT%z&rKx&8T4pXjkh|wab)xwb5UDy8}JMzK`%^jXX~$Wrn0; zr9n!jg2ZJ%&$XRD)DLpc zL*D;8M8Jk3E5bp9`+y8<=K*`z5U(axxdaB6>ZS1|HvUL;p)X!4voW646|CVuxo!sV z)vF}Zcil{^0k1ur@u#?5w1p-r(IKp%)GzAv=|c=F)Vq@CVV;9uG7Sjv_++ zIZiJ+pWCpUn*YMYSbu1Fp`R@HbvQ0*&rgAW!leJq1(R#^PLE(+w& zI-j=4U)>s3^b5Ly6avV;5BK zWXmvcM}bJmo|81Pl{;FhB}e^J4t_8E?(Ue@qu-*t$mwbk`1R;@Uj%f9_&QKKQgw16 zhsu7$2H1DvM731rqEXsb0#dPj8a7L!`{MEo^}M&GS11j^hhn?+_CJqPPzpnP8Wu7h zb+J&-1tR|$Bv}BdH>iAIQw3|Z1Vjv-#nL~aMRh_AIC)z(6T%fGllCVE`W@z-L8u)= z*59qWcOIb6&~2kzGJ^^#+c3GjdQ~HqyLbq37}Is$BnD3O`J7taO_e zk}zzT0H{sH;NA&RhK;-)*zxl3mdT0+_jMfV_5`v|xV&w{oL-8^1g4WZVYU$*md|~W ze1C+5Y>;|A48)d&w?o#ep+f+HG^L=86UkU)VPb1~Ak3EnKG8fd>Q8AZ56FDagUXp# zj7Bn{&mSa3)$<@m9&NHP4`xk>>OhwR&u563S7L6YiF@XQ&U zESj)eN_xvAMppz9I7HdAH9I&Yp1Q^+2etd-a%V*|%NO;{%u@X^$^H-0;Qnn49 zn*wt%DIA7XS7K{|8$8X@128t76eBeD2q~kv*=beuOVcgx*$*xHXlZ#FZ1Y~OBAEM~ zt~00EYW_Rc2st$nRfYGliDs*Te{1f8hPoe63*)vGf+|Rn`nEK?x!$C}3NV02df*bQ zVY&bDIq}Qz;joXwGNV3@xua3MtzX|4&?Fm05J$3yEY_%JC$k)7fXOcy7v-vRTF zWu1bh{7<$@Q;fdDfU>_Yv3QNz!RTyA-QXp`U_Y~8vv*uum!m4SH_W2^=LsSb`vGxG zbb+*Yi0tV%kYnE5lqCfQS_o7jP5H*Xgo_l!;vvXhv2uJqYh5XR-7y9oEGSq9^MV+m z%~p|m_39n&S{W8N8cz*3-Yg48tz~d1k_0)dM8N1S^rr(M5WUQ%sM(NK&`O1NSVo^{ zR=KPvzZja8PNpe2gu?%gvA++8!c+m3^CNVxaUkP6h0b}czVM@8gg3hPrZ3q7(AJlD ziqCZPlq$uHA#j~gq1=nqxDs;?>-+u`kOMw0svGIA*d9X^eNR^bp{=j)>SwSCaWv?q zA+sFn3!rp7&j$tV)7NSJifZP23rEXp*!4tSM#YdBaFOWVUA{?Qnt}4esC(~!R&gIC z8UjlXPO7W&0S?FF_Z^yRKiJ`_9j+l_+TM+OYBTW?SEl&wNIVL6{?wWG7|tnv-3`6K zpR4=15c&8S8EV*MmB5k^ze%<#8M0?{Xmy}oY)o9Enjj`~iH5}}K{u8CVdbztpOn@~ zEt0~Hk~p}WdV=3kFF#0Afk2k+CG7k(b^Brm8FI5di3JkA8-OXAn9`%jrcfv0;Pkis6_T;s0;cfj zZ2ouo5%rw-pPeduS*~?PHGoqf!rR)Dk0%LwK_i#w5mS&tq+;2Lx6xQMq;c0UM5?+0)*|yF27X{09#x%?+pZ zt3=Uof9blRk}_S{Xr4!wUk-aqQ&Y-b86CX&Dka2do$-3ZRr;(XwHSQ`Ozy~rE+QD} zZ+=e$PTIpL6R8G;`}nsLDWcZfV7A2P8PIycpg`9Ld6;rD34eXv9?>X&5}p=)pT!7d zI$mr5*&W9Wue)VF=l=F*k%2s^_}}`>0(7=H3>!pjAw@NGO98wja2|QZ zYe;<5A)`cibp5||Y5WQXm<~PIS~ty|dFAw+O&7c>ETz4XF_2VZGGm&tm8ZXxXI?q< z7D}8SrqY}N+tyo(NyAPXHV))AqLU1XAZYUL8la>1lxLUU+{DYfua6=XRo(yvBS%D& za-K+2@9SA{w$_Yz&V-ji$Bn;BrZAQ+IQOVm1OlmakhvPhCZ-SDCb5P10ai<#$@{eB zxCAjCgQ3T^$|ln;9R)BLPR{yZ!auN8zKl$``)!dJp~O7E~v;WbF+>_P94!sqe)=n>Urqkc`Ge{xpv*AIOpzq6z50|Y&oebajqYg zk8Ms3=xGEQ4K$q8WsHLoIth-qrl(`lKhHLJ!w=$>3_Ts|RYBzqR3pC|muC5DJy};vBUDh6+lFbO<}Qz3Z0bWNBL98>NNp*8_Bla$g(2h% zmb80eYWT~=aM#WXGrwf4JUG`qd$UYkY!4_ym)QX`p}osFvJp!BmN}yt!89{bypWqH z>FI5croG4dH{@>e+^}b#Q7wg7PP1J*g;5IoTao$bm(G@TD$2V5O2rIR0MZ#+#f|Xf zAfr+fKfmTNx$HHNhMAjvyRtDphheMfCoX3bE=*2*0N^KEX9QSOUF?Lnyvc&#)8Cpd zBqw%@cSL!s$ncAqg3xJR#SUex)j|i3enr1VRMPmA^yoQ?YQ43R6rhGnM{ocijx)am zz zn(FVU%B6_}>h)>dWd*YLA-?0s*^XcioNEbEdFA+{_7x42#@|4Iw}QdBbpmpYs}K!7 zQYSMR4N2Fv3+4=zG!jrMvd;ZrV3t0NAxGe)KY6qW7i&_V?Wvl9@)HWbmV1$<~ z5qsc_tj8Mod^wxL;jTQH<|0KZN=*@BF~D33gwm=$9$0_h$za;Q=sES^tVs3uoO{|s zfmtn2Db9d!zLkRo$UX03!P}uTbg8%JF%Ywvcu|ncR}He4P`zKHWR*`7IOP~rK2y4- zoX~qr3T%p}#0#_f3g7oeY%0Iydopeh!Q6$E5sPz0?Hh?ZpGX&2(6xI0cmBwEkm@Ozp`eu@+nCNj!^gU_d%46bG0 zn3=8{a=!ym%iL(TgNg@KJvCIGt4?ijVJs|pOcF>t88wvKG zRb;V%BBxF@LGux}CL&J5N41KZjZ_85x_dKV9nXSR0i(;!r0KOyni;wuK>f;`)Ui`V zseExz5#mL!1Sdzq%)WJow?Wh^(_S*^R8hC(2la`6$&efA-w8ckQqN4&FFgX*eIE&g z=oeN9UA0xDU#$$NcyRTStGxgXctXKXxrc2kJ2L-u%jp*&@+|uV%F*!l`BZgro0$ss zyPy#JDqRlVkrpXST-PqP@2Sf052bH4L2HR?5;2UVm{&~Fdk55~%w!3ERB1Y=S?r@Q zVMUzJioNK$kJ)X8Ge^;`guwK~d5s6K3hg8GMP5L#o&(TwxL!^G$IV!=v~UzNFBV$@0EUS{(NDa-nE!c^|7I);e~1HF z{F|ZlwVmdkdeqda4+DF>O;9Pn=|VKF%)}~te$hVnP}u!|A0^e8(S!x4>hF35?1A&^&Z3kxNLwc=9c0+V7={w;e#MR0zyl%Bd2 zPux6*AEzV6luSP>lQ&UP>?oC9YP!+;u4t(!8EIoQe~cAIfzFq$RK0;|x%iWZJtj}j z?bwHlEltYjVr-ZKe8`p~H<|h?;hfv5$ad@=j6``pKUzqPT-8C2AxfsuIq3wyqaj}S zpA4wS9%tIZh-0N%z}HTEmGp>S1>dM?iht}oBo_J`cV(In%tBL6v2EE|4wqt@y6mRC z{dhCyP@8^)z;))ck~qw9FQ-TAPIM1V!xn`KI!Hw`4GHozxk*@K5{GuC)pZLRu#3M8(0x!#-qyPRn{3vhk3Y?AVsIc2i1tD@HGD{DXs zFWBk$t)RWUDRCfMFzL8C`c*v?j4x+cLC}d4!;-E|$7GQvCo>i<{55OJIa^}jZvzuKkkH>4m4yU{)f1k^xyN-#;wt!Y(VHwhq?`?j(h9@ zlz`#xsvZYDjL|frq??(to{mf&HF9p(3!kB1V1>f%KAHTOjes!YcE~unbk;6Wp3Tfg z_k+o9MVB5Bs+zB&nG?~1YBm|H@2;LO3!4Ib(2a0IU^w>P9i^$!xmJVX3~l4mO`c3~ zwJ-MG3(5?u*^<_VMm*ny79F+xLd%l}2U-qFB>5eD zq}d@_k%+3Y0=H9vIjCo#8}Zhdko9UUa0RAql|N*Xo$PRGVbIojzbqbS;^FQIBQUY@ zE9uS2+ls&r$8Logm^(pJ-<48xPE&!{GP2$U=+@McGq)~#g1s0N1V3fp~Birv08=a?$r#=%+-A<%5m8AcQ%A7K=%qzO`o z)?LH9)Ms{$N$XRqI-&d7T z|17DhvOKzP6yexzU#6wkN`jg@e34Q*`q!WJ80Eb$Q$!`1p_VN5t1!P&WoQ~N|D%a! zc(;3a8kd_|Y(c#mL}}~5%y(ZB3jQVPMz8O%ZKJaYo-1J@sEy49IIK%$QgFs_Gx|(H zCY0pTK%_rN1lYTD-)kYa+!35XRZs!9CX4RG?bozya3QLoYoX3kgiG*=$hbD1AG_Ka zMN}6R^AKfegSs^xB7qy8*y-W_LB7`I5u-EkYWk7_cRDPJ zXx%ZMx`%OP#P0~j<`146rdB}jxWentu+7-2Fc41p4q0nyd@KW>>25s>x@tH!?E-&F zp6W|6ZQ0490^lOSRQp~>yUS8Ye=IP0g_7CS5>Mv`St^9)?HZy1Ve=N&L_zD2q?Glz z%g=$ale^h9UGslGyyn235n~w`Lb!YF*T9y`@~qckP@Tzsq)UX~NEQ-l{!jogjg7F! zVYm*+0|1(i)f*9%#|qvz$@wMk-iVk^S~PFpYdtfM)vx}Dwc2;zvU#+qPC|Q@!entU z8i&+mLy?uO!=vs3*x3}4dPqx=NP?i33x#u(3RmLZD}k#25a~dS)l`42Ao){a2LLy= zWbWHByMS7!tqP#F2VDA^UqYb6za;jAnT`q=(Qnz?8tV|4VF2%g*yo8z&%L7zfUvUE-w5<)^ z_|B_157B1|v~+E{S#*9?L!la}o1MNG>nVEu5So18iV=G!MEP3o@>0jW<7>TWm?FOg z=Rcqw?VK4&Wm4D|V$+I$s}wyGEjw5?SWU59xRTRO2L$^ z*XLYAwX3Pa7)_H$=Uj~x z)N04dYY(qtgcQUj4MJ=4yT6^ga?JP5@SOcy!{gy%6BU_qz^vpggbMp5Y@kXilNpMd z_%HfRP)ZoLIdu+`lhg38sj?qYL()deV;So3+!^8d{uUwotL``Xh3=Pky@E{iGRT1e zDhK&uuiYArVC*e33Kkfvwj7yf6sLqmIFZR;6*G^g%{rsNPqP-Q1e%VI`bcBN`%JDM z-hOCE>w>5f5#L2(xz?YFh%;yTYR4FT|i2HVWrA_{9=4q%R5Mp z)+_6`-U6F<(lcFrs}y%m+*2j%5^~6ltL-*ZY{6)C{sgQ;6m*9*5MWt~KFb{K_22-} zuzQgBsKj91w!&Y%NzbhXIyUUu6x+LdzV#xo^+?5L&sDyBn~ZrLpILao4ArhAGQdu@ zineN1)SkBgA%8kT`rlvA@%=*lzWTaJ?}a%gAllxPyOZgdWhV}DRau18o+<(dKjDB@ zPy^;Wu`(nqzt}b1i>e=j_MZ;G0IdY*su;|J_EAY~WW@S+rX!mW3u^#WjBel$4(ss& zPP*Jgz=~BGOnn|)V$b3f4Y4y21&aAw8dTT_NYeHcUt6%9f2V{A6WTG&V<%O4FtxXm z4&5smYN~{KIx|T4D;3qB==9kfdg)rO@Izyo3pDw6Y+FdFO)CKq)%`ukK4eO7)xzz@ zJC~CHbE#`sV7iPTBBd%ou1CW^SKtFtuuy4S-Z}YgY3qTt(z4nVmyT;WJ&nOvu9Y4( z)y(OhM9T;vm#>n8!r;ynKrf~=t~5})qg&y>3~lbK#QW(R zOd^!EgPuQ*N-pfBBpgp10$WAS{tzPn1p*0gf@{Kxd6}5Lwl#&IsJ#PIH8U1qw$5pc zrhH55Ogk-f+wnEkR;qx-UGzPb@%dK{F-%tSfKpGI^tVlTv-7|POQa%2h|*o%2KAi+ zF(>+O1f2F}c#eIuW8vnDNzNtanw3QOrZ-(}8`9l|rXl488(O5V%BO>)MEG(fKTXTD z_{*ar4)O1AZUq0Es;O_>re^R1ZsZG!ZHgiPWqGl2K)o)sO>G_;`Z6eLrXo8m41k+& z7F_;yM%VPhPkV-@n$a4}5W#ANZf2(=3s^g~AOEWU0lz(=Bb=M{&t{VkQSD=sQ8Q#Z z$4jCKjX6*(TrK}8fo=6yvW1Q{eAX_2D!`#!GArfew*qKjDMSv5FoQM;+TzIbt(JQ zZ?fT4FX98NOTjyALw_WuQ7Le~YBNw6)}dJoQ)h%86pyEM50Yh0cb?`Dqt3tX--M8G zvYg2XNeISkY3x}4HI>Hr)`$+q%U72m!NW2A;W2r?4udC>6;nXCD4>ckO4XH0c|c$X zTha#mD*2wSR^j21rd|Y8RYNd&H6}x={#z%gOQa45cm-6WU$`S1ye3cWx=*k+DT5nk4_z7}$;&~v) z?&-;=2YT=gTN`i~+orm-HJ-^tuY^^MIfZ%fmQ>3qlgq7UA@kUH>lDO!B4|1nez{}E`|(OfU(Sgp=!fhLcQ3`{*u`=$ZIuxb4{|&F;~eL`Ub9t6 zopG35k|oP3A5g=4zmZ63U#j%%X9e_`qd$KZbAR>ec0?zF(rI#MPo@8yEF4Z&Kz6wpHh)A9C8CqSLF{xL_G?3*0-o5rNJM z>*RM?0O>@NBmvT^gj6z$z%JveS3kUiW=a4G*Em$t{CNUOft~B(0Q!0{MDiycEd!@%i}J zr4Jn3Wm1Vd+{NtoGp#Pmyz{`mP=+S856Q=qx3YdFHond(OcmQjxUj^FnMO3I z_mo4;@J&;t%u`OSm9stZ|BGY_Cb7t@?bT2%14m-Q-1U#V?Y5^(W`9TZ@(@Q3PA%cZ zNUb3~x!EKz6r-W}{ATk?(geQ_c%&b;gU`o{V8!~!I<;4p2sw|OmIro&x=GAMYEgqP zG`%+mK4XNYYuy*fU>BCRrxYwZx%)O2MS_4Xn;bqfecItn^6V>m{90fg+hWiVgR~VJ z4(u6L>AeMBi?W%^oSAvx)8p4xJp_G^~+on8#sN@sU%r+!*>e<-R& zfGKHQ5o@N@e)^VzojGK5y8BfjRGuBftV_T4u!u=Er$31d4u^IYuT+Fr-*{}Xw7QJ# zB+UAG7>pwK)#>}U?MT?JZ@{u>OPJgV=#N`>a<3gwUU4%`NE<`-2{EYmKma`Y3bZG- zy4D^<;dSHFKq!nFKXZ$SV5Wr-IefDDP~q{kMcx3JiB+0M;-&L zoyl)dUkx@k3HxFUn~4|+G|d<$1)rmQEF!idv^$9uqE6rzK{v@Nh2^wZ%8H9XPB?`N z!Q-8i6zKr_=Aq{fW+S!7g-V#d7cP(pB435HD>dE-n?=0BMnkW&${^<0m^h-5In&|9 zlR5r$*c7rms#7{KV6w!&8AKjmk2N=6R*u2^7$x5OxqP!y*!9V?AiQU|*TeXr(ci=y zeJnOx-YjU6IoWWH=ChrvecccfZa(L;pYm-{0*O=nr6slLPJ<%3I?faJz}G!9#En(~ zhg~(RHWfLr@(0+hMpA2^HPsH$G0%9f_43$@91RJ>1;KJ6XJHhP9~Zewh@L5{1A#Z2 zl!req!bZkmrs#9VY=jJ}442%e_HOK|My@@hY=i1s`G~$zMxK|%d}2#OV179=S%P)= zx>Wuni3p#mqZp>Yz-ceLy-6XK$feCL`ACD_w0EvV*C|Hhj2*x@R9eM}O!0av9oxj= z%};c_e(&1)JpoE;@(|iMz|fN&0|P+GuF#V3cwHy-7o0N!Jx|mm#{5LP&$UxG4fozG zbR@;yHXTS!RKR-iGL|>-7wk-Ja_H$V(cVbZ&_buxhG7))VBe&9=jh{G5b?o>CNq{? z41oF#Mu$Y@6eu)Hs|Edm<_wkt=2XXbZ7ij^fmY%Ui}{|;y9>QjkI9R5xkdDeU<#qJ zorRMnP!bqK=1BXCVrAcyN%_ij)D#&KLsW(1Lqhsph~!^8o6D+J%MR0d8V5t$Px~p=6c(=k;XLPe60{;Qu{-+I3mu)Jxm!| z3m3q>i12Bvp6mU|i5i~Fc{=;h7oZTxC*xJbA2p7DNHd|_i*y6N!&185)@TNcJTwAf zJ}%NOo3~VLkuALY1i>Ew(_NgPOG5OP6zh6K!_}gnjo)r zCBn$uF7PQ$PTQo;y}ZpYrKDCSp(xVz#1qhUgRs^T2niXV@!Yr5qi{2;4iXpue{A0b zpeybxtzE)2WZ|JS!I7UG3{4#Fe!ba_rWCQVe#;{`(O*6jiIM@KUW>l<#Dm#z?rT2A zyGll1T))0iK19}%5f}j`95IbUc$k67UFFML`5w&rhoZlgbmj97v_*O9K$DAUoddj6 z9_%i5T@~Yt^@&odomuDkCZ(0E^6fI`OO=>*8QWj1Hi4D@27wGs5jepIDD`1HDihw& z&wChuuXNV*Ih=L`)kKzi5Of)IVPAhxvcd+nCR0?pM`akSLN0R*3)jnTIJV$1$ZFWdT3#c;=Wo& zw*M4IbEjYihS#{(n{n&KFoAcl@hLuMIpl=JFB(R}%e}zw!mjfi^sA_xYI&#Np!Q(% z{31DKd$brL)WqC-SyH}2;Pyg0mD8?ue^VeXf!65K**jp4%r3KLm4X=RQc#Xy+pSwE~9& z#>^X<(&YC2?p34HA#DytcNN@W-8-2F%a?bL<@ zu~7$teIL<0fPx)k21A#iU^62E3PNm)5N+$54z&E@N6iyVhQ?Tnzv|ZP3vUKHe^SQv zq;C5YK13TV1U-T6B0ol%yc`}u?0mB^ZBfOkBw+u+Xg10_S>$3I{)CN>#rKfzO9Hf2 zN}aQajdg7|o}W6|4;Vf9(S?h5KDoAZe|L9>n_4VrnbS5w-po{A4o1^*3x+|ny zIcw6-q3O0w0M~gSkAXFW|7~%&)T*V33spo6w)k9-`yV^v4^ z!8og*A_i_TakL`;wtMk1Co(a);P8ZM5|W$3E|$4d>YuT+X>D}~W40>56+zz8Ap|pX z9W|c?wg-(2chU3>0#tTI*FI{KwXq8OVN5$D|dkDcPQV{Gg-T)RATLv5_*N>b=f4`dW# zwPUaxq^QvnucyQ|+7_K6+OKEbj1V$mcFH)4P7>7mhRYm14Au0ni@bCs z=Btr?*_VrvNC;F5$A>E*06GKYm zgI3q5Nr2DNJ3yS}YeXI&ZEP5ySv&m=1sXHQ=8QW$)4sLkX`A|MZeRey$|ke6=w zMQu4)xCcrS|35_Cq7@Vw)Fl1`K|>2we}TkdAKc@B%0w{>&9&lCtDrg=_{5?B&kV^< z&WP^d*S+3I>j;WqGS|`;c%$b|5Tsp_Qf9BzOXatxs!zoGnvGg38*JvAk$gCXUjCiM zuYhY282L==(vES~Ym9Y_eV>psBLRn=R2=+EABWQ3v1M$Dt^d%BXVz16p(?v)b~o+O)2C(cWUugO6oY@^0%8# zq3|*WCiJ2RFjhi4az1fNf{*@&3Z#&IZvvYfYuAK6mg&US;Jfw)KO1#a41Gz-yN;NT;V%>6 zm94uj2zyy`G0M$6>Gz$D$yS3*M!oDGV@=e~kF;h-TgboOJ2BmPy_^h}r9>5@#joD& z_7F(UrR-Q^zm{-Gtq8G%Zv)<=Ii3uvInd$gbhr>ZzpLTmFs=Y^CU~<|1UIF(Snni9 z1^PJ!YzdblpsKWbNbr_H1+@7FraJDQYVO7l`nsepe&; z^^s?$)z?Fc)f@L)@dPYEeZ$MrD-;#v9qDmtL%#^3=Lqk^HwiexAABlyI;!wEG@D;I z&m|!)Jj*D(8Z8kQ3(Q4J`QR~1QHpI3fbpMLGKqRN8B={N9rNt8Z}8TZJw@%UM7Md( zuLJG04Z6-KTX>f^h4ISHOP%|@_hjK` zB#PsR*!JTsxO|~I8i`#k4SjBQa}X;EsuuRV)xg^ekdpRiXP_cOpYUcPtH?QFrFGw) zyx1xM2Hl+L&;>uHRaHH%)hOU1RzN0&xR$BelTYM1uCP=Z2PEqR=WdW7Q$~TYp^CvQRot|wA zm{Wgp>dg(d3;VFaN5sKLzv<+k9YydN`}lsYdEY4c!zIi~qE7vHI1q_Ubsw^0QJaDQ zwG`oi!BJVlW((zo*q9$XmoU4;%-|jkNGeQ z(Qk$IN!r+J6!`zdGB1?aq)|>rr99){H<8AcSoGBbut$%jmyVl5M(E3w)O-Blr`$G8 z1DdyNVbpbilpicsI?NwSrN6tOk>4-pT4ff6ki-jmThw}9RA3LZ$FMG??J*@END8iw zxH4ECu$A`wNmDGX;Cwp9OLT`2%>rM|tDCe4I~vx95xbL6EwB)d^Po~6cca>!8jfr; z%x9JHT5X*h5Fb5Si6<)f|F@?VK39vfC1Lij>_P9|xv<713i$=G+(T5w7uE7pXXPcZ zpwh$Fj=GLkKLAau5uslFGpv!Hn;^%zSebMs-@M`Bi4yLyV*bDnM4T0AEiZ*- zQ-@&?74#A!Z>-LhgfCr0C1@XwsC`!-I~x8lVG(vbl&3xJg&EWvI+sP42rO9q#I|~8 zD!u>YpI!`lAKJW>^pv4}8M%}GUnDa>Bb zJPUhtBo8>^Ng{h5ktcEZUc9^I&fHS|o29KV#JE(5Xiy570MA9Gce zN7t6!B|SQBCYFf@IQ%m((3_Y%X3LVBO=>v5Mn-Hmvsf#02Bq4EFMFO7U+|L7D zITh(17_%PMmoCdmP<0Tiqx!iLAsd-ei{Xv^G;gn0S7A4h#Hjd zDjrzjHF-)1V0pw$iL3m3?O+5#v#VgF^Ht~kX&Ym!lAMhdFD^VF3Em@-;<0c`7vvd5 zZ04fGV9zu9T^!I@ht(&7sO#+gCVDuxX!H&Y&~o@biwYp>enoU5RE%F1n^j1lqDM;F zhP0A-e}_BAh>&RHR_G_toSrap%!%V*)Mts7k9?F0Fu1iFQ!2J=^QGC9ry_ zP4$xRR&9(G07fFQ7I#;bqggCsLO~~vk%y}q6+wYQpg3qX4v0X_J*4%rDuv+ABUPPi zCIUloZWbkx$iD|o#i&(9`Yu0%d_4~ z)s+?{*tI1IiB>oAjyF}B_2qPPw$y?@dioRMHbBIb=8S3u7Yw@BlOQ1KYb{Q7bg{$2 z6Hp^4v?`ZJN$#msQ z5^sw<0hYW*=($lc?_++s`LK#tz?(h?+qP1-mr{R`@{2Pk^tVQzsfu@(jhq}9Viqg{^T$ey1utJl3_?%y`Ks2;pe!9!DsUyEX&w` zWha@RjVo&jqG3(8|9Nn_v2iB82qeT)@lZl?0E`<>3;vq$F=RS)BH^yO_1+^ew0Tng z^IomZz9*2`opj^F975`W(|AXQU-TC5tPAb-AP?MqLT_#{g&KDe3=9%1qL!td!f4ot<*DtU2Q|0(3 z1nko&IsNKTYv)Wzfqj|^6%;mRHS8}jg?M4oWM=~nZrb=v^jizz5a&FH&k@NfvXu*) zfBrN$(>L;F>BCy~68&I#x$Z=uESE|+rgHdU$z05tKsmV;?=w#Axq;S5zs|teJ-ti@ zh7&XL9@u%rn!(DRcGG#Ev+ z$yrn2w|JNA0*0Y*6rux34MewDx&1(v$?E~U&xM zxhX6&wT9)Y&4VdNIoApuXsbKL!7QptRX^b2I~LX_ zlHo~PCI%vU;tjDJERUb4Q!95qPECoSBtjeg{Vs+=NOfGV9SlSq`)3BQ%OktVDqqUC zdIc1rg_lr`P;$L54WIxckKG<#%Ry@Yz+UPnn$q%SX&Cnwctk{apuG*bac02?mY5vp zOXi2o4IsU=7oW`=%TCvKqq$W3h)>IxT7FFv)u}Dge~{?ZhJK+VbI9Sm`Ne&YgqCaAAMJ#Mu-OThD_fQ^5hEgn)8lYaHLnf`frZkUTA}`=>lHh?F{d-Zu7J45 zR!#5TJRD&1VA?ko%)(M{djeV}N|;sL$qb;yi^ZWDwDWpJ2EqfTkg-g_NOOy?fxd>J zbBAi-^C&6RVC!vIZ?TLYrWyUUGH|PF4BK1veaEo-GnJG`|hSNnT&fNkARlNVD2uQ z2omh;n4K;irx-TS8h3#nnW@*Lg}LJt>{`$AIYWJyHLpWK!JJu!4h6QB`N;E6l?1L< z7H!3zqr(mZP$6F7U{aT6`0{9${wQ-e(9x^`=y+)qVj@!$Y^B@O+pV!gbVj$Jt;!cx zeN?Biskxagf`U5?=>1LFY!7;eUEyT)Z@W-o*Vyt)M=fgn$6~g-8a@7Lv9%83LtP~W zW7cA%c}4af`PTd07pU`Zl3~KNy!k4!%B<}E7p|t-XTsD701wTnkPL?E&w-kk?@A9o z=5@&>_AjY^a9tVRLIHLO6;mkpv8t-}vWJl77;!$Kcs{FqIl=jnGW(lxvqqP>d9)d& z@UtZ&+YCO~E>3|2o0Yti0a+zj?&Fa7wSItKnOxCcR$WuU0Z)PV{?W#rGZIYZU!+7qnoDTY&Y&-K*QJ5U;8L`1@(&DUtgB#fcT`@|Zc8`z?1*2xY*^sq`kn zPLS5PYW1#hP~Xo2`TdUuL9`e3<$6U5AR>S|y@{~1kGm_tXCS@0{jP4>9kVldN^L?a z#!9Y`O}qoUjl(;4*qMV}`H?@_yy(6M*5$&7?cM{`EH6OZi6@j={r-Poc}@9w!;=`iS16l@x%~1_)Wj3*>#t=GQ6rJF& zkyIxzbf>5SzQ#nX3E-<}k}7Px%I3ln8mC*y)z>KtoERT%w!mTcz(O5&7@B_fcV}!* z*4tG4@G!`OHr4}!d zLTXHgE`jSN<+cr6x?(e5q6V80fmNGPAJJhaO0a6odKm00sPz~C;T)DH&<^^8PMzis zh4OI8kE`<-yFr^cq`MCGfmg|9@NjF;)nOYTeAJlXiMY6Mm)nm71-IhaP>%Z)1Unt( z#MS$-6_HL2WJ=Kvx5!B4G%zD3&}>KH_P{oEuxy&~5AXoW-Agn1oh06SlRDrjUWFOz zxYM%PY_+1=grXD-{|qOtVZWxkDVo&D!V(a~yWXls7#x-Jy_bljTuMS`J_-HU(5Xrz zo=zQds4$D?2`vl0(gUYteyPV9fSYonjSg|S<(mqwJq~_18Q!}dND4;F?dTJO8J%vo zq3gbA2M`4ehW`L@95;{BHB&z5lOWw9DfT&KC+&ei62f%o+>aGnVL5v-$@GObHo~_x zC-$Y8Ku)XBZjTMq0TW}B+c$FTs6NhZRKXm^n@T5U%n{hewtU^9upAR2tr{=hMaQ^u zd$0X%M$9NQ#7?%lHHu4&Nw2(HI=}mtK2C>pO-X2sKH$N3wSiL3fL{B6U_U*&|6(6b zILRV`5O03N|A51T7HpA=D&_WPb-rUNA-~y6;3*k`Z=jpM`7bd->4b2&l;FEz;b;@u8Nnr2?15<)K%AgTK!O{EmL0 z%QnINDRDWf-_dT29Dw^v9u6o+B_KKbMwf_=c)VT!C*)o-3FN;zkqpcX07BD#kM%hO zhl=aCx}^z;Gxcqjyi>`T;nId1VRCO=oCa3VaOr~Hu!d-HQ8)QtBQA_UzN`toIK8>I zZk;Aec4`&sZmvNh_~d{!ylv4_h4sD085ydTz^{1aH_D?ewReyMAETtm;d0HaMpM-f z(*Ir8y%h1#RzXF>wEf>`YGN*?485zKkZ~7*JOHTdGNtfcWxeN z${X}WV`Th3nu7k%$%kjkD#2*l-uoazUx!7&EUYXo#dCjD<$H0w(g)S0gi7Zq9<-V( zhyfCN&o_v#d^h_bSqFDLL`&~eFYlut^$;XuwhxEld3M?;p?5p$+hOFnKrFNhaq#(u z*i(24)4J>4hIx2hDj7bF&APZ5K}(!*-5i$Y zc2@4_1f8WXiNs+YQ4Jc*Zi4HcOwli%;Nb`myxb5WHYiwXOpnWh|QIX{!ClXBu35j4tv>*m%V9t9@iFsP-PDl_lvPu|qzmkEAf} zy9k}|Zj^R=Xq%$WJpZIuylhhP_PU3x{@%D|lOb)VZ?cWw9xDREb~-4E)V1PjH@ryv zS864IdeSPWYAGuZ@0h5H4&b-xXgsTV(2}ZTL?Ne-PtqzJ6{_V@I#5b8ACQMt`Ws{z zl{^QP%5roZah2uS)QkD*O@jBpaYq-bHX}_!x3HyI^OtS<0=Tj-BQfgs_20nXOzw)& zPYy)G8WSq!G21C>dI?I;Y@w&^Kcj~=it;=Jp8RUvnP3JYh27ELEV%3n0(Wz{-^Wi% zvFoM*VlkdiczoAX{43ewg$%LmkQJ(tRoyW7g`}Xh*YQBq=^-e1WFS;&QqW_svl-UbP92gD{9-vuh2!ex^qMh34FHy6RW25XBkQP0t;lkNYO!oW_1(kih3K)j*h5ALi zUE@P>p{=7yO-3fXiHbDNE&433dppG*gs+)>1U>&XDXaYmTwwuQ8_^FJQwrKG16c7jMX_SmesIjq$S%?A z0z+!U$UG60YwBGpd#fCV#o$BwvpjUpZo6|Ff}vrt3`1gL7thgRgZ*AtZRk3RZmn7P z(Fx`a^Kt!f=eWP}&b%PcDX2FkU00yJ#_RTsOe*;KSamSPB*{DzR-C&U&l89=T*R1wtjLmcnA=7*}!2mO(s((HbuM3JiAsWf7m`jHiC0HGt5_d{z3(pWjr@_vI&R9~n0Ab!nbtqoh}sZVpXC@3L0 zBVT{JmGmScX5qDQJKC;)24mWrFK3DGxY7QGXNC5rWrIT&l+f9O3;eYOE(@qKG^n^X#b^ODy zPjunbTHhC741ccYnCnh;dHV4QW|u37{}SVZ{h?ei(78F|T?q9zuWHfkJ3<*D#7Ohe z0TzTMPkg7LZiTkZp!egbnGz;CU}Q!@{3gJRJGc|3tEyMU^5rHM02fHOp@Pf{Nbn_Y zk%xc_M>``QXN^tvWBSCAjkZXGp|SP$SDYvoOc5HgoE~_AjG^9d{x)l*6T8qquhMX+ zw#8sUcwKeDalK7HI?@Pu(pD++<$5O!1#&M=!nn{qMD3w@irWdCfz`a-hDnn0MG$% zrJC9LDs90T4<7N!hZl?T z9t(F_9ov*g@3tI;aXOWE!U@BRX-~=(NnwhcFYV!fw@J<8s6U9+cMOgVy@L>z@zl-% zQH41e2(R$1S%i_n^gZ(qMx6NL?3P`)3VD5-8#%71?iTr#{7yyMYWOEARe;BFz(5$K zv91AUt{Gyi|8-3)6RSP#P^r^_w<3C&#sjGc(=FGuUNtT1v%RU7$P};Z{TGr?kt)kb zoC%9p+eb~a#6K{|F|zsB+G_z4JV7b9e}FFQ8B|{EVQ*G|PmW_P@Hht~mln)#PKhdm z%p3}fkp}0Uu6uJ<5hq;r8Z?soVWaGdz6Ub=clR@Z`3n{e!KbGYw|MQWe;4Mon?>#A z-;t&OhS=VBNmekH6Lekuv8+`ay%L@I8uKvpw#blFclPo)Er*s5_|R1e#{Eq^r(R?f zGqA|$?jlfArcvQ~YP%iQ#292L2abUbUl*i z^VwmLDPq=WCNZ0X=QuhPemGE;L1p2xIHy6GN~|53p!-7vRcD#l;G7Wq4na!YtjFAm zbTMsJOqp6YH=dP*k>h68!nGy!~aF>u<2^tGvF& zZPJz=nQYm1KZ7Hn}-wI&~Zu z;pGRR-yV+4)@rInC;({M4SxE8vBO_YYlIl+(>51Z`pxs3JjpL%;}|vDEyzXQKNVOy zPwA+w(EO2lNy)Hnw5?dwH~Y{n#Mn?s{emwHyB1>Oafhq?i@5Z}N|&FREcF>)c~@vg zC=bEyM_a_gs&b)p^j_5){2rFotQv)gdNw@$*W~J1O!s=twJ@zMvKJzcjrt1DVQH*I zj0@=z`e%jrN+hP43XC)Ve`3ZDmmWUN2&SgB3ocNdiAvV=m&xWxYOYZ559rm#IM77G1Gj z@0HI?8JR^vN{ruRrq(9m9P7?9e(T4)dBiR47q}KSUnpybx22#&<`Wi9H_G(%+d5Qc zfE6+hu(X*4d9ayIPjx!p&)el@?jdt+teJPRj=hjuwWsc&KjEN`k7G#3V1_?OT%1`w zFvTh!T3NtqYztIP=!ZT~d%_@kP0Dw2JVW!&UtX z4B_>y%!T@Ir~-5xJ2;MI4)~6klCd(6ixD;(ul+GB-bMlROi9p^={RDC&K#CRhTOa-%My%)mN=A)ZFyb(S{6q@8?6-ZznFRP&;(tYwFG+~{LDl}aRM>s=k3oNq&(%> zA1(J+180@k=dWpuQ*?)&-98$9@QsInNkyAO;gG~}C*6(y8pS#!A&E+`PFLVKrIr!a zw=3*a-!S{YSWwseRc&y3u{teI*37FKxh{{b#CnT^4XxYC*hcIEn6hrE_k78rTwCDvM>O^;|wUCGWX!ODyNlyaT4_ygVfx<(D zsqH!vTrdbl?z>!x`kkkrrsO0S`$o>Jej8m;*RSby-KfJq0`=3)&%?jR%1xR%3hIad z5?4}#paS2SUY-Opuk&-Fv=sovVsAx2V_5h^>7g(C@P`kagk&|wQ^ z*aWZ_(`lWx_|}pNe&XU~)`Dl>HvX#mk-xaE2lBqOcHVVK>jq!^S`_@=Lua<%e?8C- zpACKcN04Y1kAJRg$#dJhc?jIP&3Td$qM?Wzqv<#D_`accwL55h_LV+=D1=!;7cT>J zwO)b=YQ=LjWH_AYL8cp1g=C${<(N6};1eJ|wj4slc>bS=a6Nnpm9;|hX2zIK;-=hZ zZSTRAkiLb#uPP5H(i?(Pl*zhm`7NLgV7W*?=YCO{cKWF^sDHh9RHyUTnl$EFCBP$h zFNM-EuaC$S{1l(V2<>f6*_}2?LrtpiRSARR%2yY$?NYR#-Tv$kj2 z8{j1AuSEwZ_nl)T)#86w%%+bjX9&&b11{e`p?Qj00Dz?nqj{2%+wj~$+a(bXbal5( zcy;tbnso4yMn7nsxmJ1>2F!}lH-WMJD}!19pSxTsYzytrnO^|E@y=KxH$#h_LU=MT z1cNO{be@O$U+A!v5YfkK37fcWoCG3q>`X79$5b*js{(1Rrk3w(Lk}>cftcgf!0$%5 z!3WH=r$=)qfN*w!S>p^XG?He_Ht96GwkyzRS%uwXIf~TnLa0@pttPg_T2wd=qV+zO z`$!u7$Q6#Y!DV{W?5nmZnsceST3Id;vsx^^{?xc@D}D@nXS-QlwpS2Q6N;9jK9XFk zy%CT{_m`Pqu z-xROY6U}B~5)cZi_WHZpm9`6rrQa^Cg?Yv-^8k3*3(H$QVaLxyl zQ<5LxDQ{WbV`EBDT7HlSK^DsMCrEizr5op)pMH&yXo<;YbTzGJOafwdRxZ?!%m87z z-mSw~dT>=8!ku~q)IqLo(IemxOkNV z%qN0@DW1ra)Uqpi!HTLM&$`bBO7rC3BRf~`aX^C?kU$s1XzCZoK=RF|+OmSiFW>f6 zl1&qln=b3JW2`@AT35$iS;3>#KQ4h!S8WTZ#bya?Abl8;Iu!R>8(l?+6XL!u{UBs( zr2j2IA&@%=DL+Vf%tFn2IVs+Nl$E&@72&EnSEbce)k={-{KD~h8`JH-gns2YeL_4)85Kl70H|*=wuMA6OG{cFrZqItko@Tg3 z4zv8By56o5eob(C_uZUL<dVRdX$f0<96{*;--FFx)NHl!Qnc?6P=SAOT0RVy+YE+gx(euRe zOHNNJ7$|ApKigJ|!W>W+%^-jo0Z|F{yw+mX4y0)+@%gE`!}7Emx~Z;OizQ(2)>oQGo%7hCSmwn`KLob=+(O`reOlC$upLm;N}p= z#&qGjB{o;b(r1e^1$2F4D0Q~O^7Ki{J03My43{ewS2>h5GX)lIS1ArA7t#LpG#922 zzEDy})d?QcZ=D^&GuRrE-YTwq`x0LxwT0RMxUl7!K~q#&jeV`EW{tCEpb0>z4>XqS zGV4}^2j6FY6&tQSWL9&mYAfc)-0Iq-;enf6=q4IU7TX{FNGlE9x?N;tS?2es&de;$ zrD4l82^|M8ydmE~dJh=KSy%BJ7t5mQyw6pyxqSQdy7`tO!$k3slN^oL7Tpt84j}-MMomC+Bh1`O#o3pT2=Fx^bQ4HBOwDFqmKz$@~+!O*s+3t6z$h;rN>O^0SJNSSD|e3W*4(46#j_()f_SFR>7@;Tx7Q&Hv9j)r!C_z+=rO& z8fZxXLz>E>aM7mz9&+|8oJS(!o3{@d;^fUp{1d86)z62IAW*TIS0TCgsKmhUP<%Q$ znW)YP{hRYf4v?6Cpx(+ARJ^;7o{&OWfIhEZ(^J_MXS&JE0)A*_-uwi~Ds--S4AKB`=o)W+LpDwUyMO|JJZ#cy8@;L_g6d!N9GhNl+<= zCc?@*rj9V8ix%X~UVy>~I?wd)01xI;9Kkb8!Y%_HSePp{FG+dRUYSm*ZP``NdEMW# zGTK0@nbyrRz!X2enIfAwgATkuWfqbkGRCxpR{(bl8{)K`g|+a@C-T_*R{v8JC9GVi zcLh`~(h($EcRr7sQGch}qgrut^IeE+1TU^pMUDn#_|D15x9+CD2hMkC3yf?E4z>y) z-k9w}iJLcT+ATdw839;u_4!~bu1c3n^_ETW`{`4y)qhHan3dG6ggv6kFEY}%RtV{T zpLfI}b0FDf0-)-8;_sr3rMU!V5b>J`35kDWE185S$dJRlOI`^~3mviO!8MGmp4hzN zcfu)&_6F5#^lXYD4ql4`>z?A~cf0WyFH0K&HTQLc%|3>HHBmW}=7IqjqH>UY91Q?} zGYf&#+EQH<8)$KMBlWbWd(T=2GBSk1e4Jiy$QM^!?+P?1s7*gw%%V+@Anb^Z(657R zSaA@=K;k*1(71$9TRGggRC;uODIT#ZU@)+5fmvHUvInsR4H|W7|E&cOqo~IxC!Ym4 zd8j=>@7K9jYufWFjqU1~vD0gxDZHN1zNxq%@5Is>q#w!BkB`T`a$Md2&`%*M=R3pg-t8OO1bQ0lHKB!zmklkb~f*&21p0)3o#r%i5O z59kLafahxiKN>Va(rWm;&vBfuTJn++hbf1MPJDZNkbjRLHl+wob>?vN+S0aUwSDTc z3|xdcfQuL_gKM#!?Z&6P$kjR`GllHzDPWZxx=zSo+izZHnkmM-Y31Tp5RmEecU4P< z@HKIh!8x{q4N)UQ*Bg*{b@YF}Rz$i8_PLf|1;CmD!CH_!WdeE{#KkdM`T#~{wP{YE z8!q-WJcWGI9EkL>jrBQ?`)DbG{s9iOIp8qpy70)!G_ zKMDP^m$1ioZ|tdoT*|`F86t|j_zSk!^b|**Uz2qlwmfw|*eF!fG_5H#-ha|T2yZL6 z*xSzX38)_Ta}hZiae$V7)$6{So)E(yz4`KWo|^>EmV%j2(rwRoLsgn6HT6^E8u>nW zb}wtCZJ^e~rU^5|$L{FnriNoPv-0eD61=iQ;dQZd&T#Kg(p`gudS}$G?NGU6JVfF-l*QB2^(6kUYWCqiRkf7gcSkhXKkYB|` zw64dY`;RF!yW!Lb*T4~a4u=&eswh0-ZG9$Y*>*$zdbi>sX_ptQD=H#=tpH5cDU&bMVPD8QX>O*dg#7rqaeB?A_L06-Wxn+J&LM)uI z;Ce*_KD~8@D1G#fnIL~|Mh$eFPaAf*X4ZgKEn|WqLI0yq6QhO0bZ+eug*3B|Rdo{; zB-n~9WgVML#>kY%fH}1GX{S)|->F2-0|}FcQd#|YoY%0ev?ka@8;Hv)7x&%DRQMiv zvBdaPI8TwHST(Ejcc|bw2(93TUZO=j^Z{PL+h6w>L`hz88!*pGAZDapFXW)sm0K`) zZ}4sV%&?fTx`h_>{+ar)8xs~Bn#}9YfEdS}OKVO0Kr|l)^I;jfM~B5xl&JDn>Ab8_ z`kow1?+(gp8$`xMaMNnW^kCGGrVOEnNsuD!_nX~)X22f|29<8f0mO%YCClO?@5hLr z&OB(EF?nh!U9_MlbOnFIZfY7vKwvC&LViT$3JxDye(7Kt+DITY4#mI4qXr0aH{55f zf-1T3xfT)JL2*79iJ!vEc3=`J&U}MebN@uMW_w)z(1}8}iYyBbCgYuLWn@{9*GO{w zrrgj6I_&%`@MP;*+)eRb@u!4XWKVDNcHQd^$%)5=zOpO@-Far5EZr5pv-*N@RE`O9 z6zi8(ya}v=^d75uC{*d>d2=lcf0Lj`dBqX%j7x7WZ@kQ6Wm7AFNg0=jO_d;#G~ zlL71WI5yc3Qrs5w?rDuYVb!GogOfZ_DU$dUsi)3E{}^JBJl&)DPii_tN;HTAjs5K0xfZ6e$5ApfginGs;A*X5@lrou6iI-B zqRAv&)ssXF{w@-X#Ry($=!&=c-=#UnH6iRUCdI~rAG1Hq94MgXk1&8e|t2yipY zjQ&tqI+D~Xlw;#GCz(WsT6Rwx9H8URbfidSzH1?LGPo1mRyi;Li|!l5m7D9tky3%g zh>50ckfIrEr?y@;Za(!ID4}??4Tl^uKWSchkze&z$7@YL+7aa`AZ;(wIM-rP+DlQ zc=|K%k^ns#OX?N*?Vc1e2vRcPE-*gt(P{47WvFTCO#1sz4PB~mm0vK5Wuf6KDRm{c zp)uj_Q;xADk>*gnvSSMp%)OLCdEk>OQACP|r0Chc%F;5jNMpK|n5_l*QPmOSSel0F zjDJG#@$!!?YKoQAi<(@=geP_`e@@W!-~g&zh}1?Q`f@)vdDYbVV@G=+ZaqX?=-!JY@xf*rJZ0Q=n z6V_Te)?=QX#=Ey>%g!+2)-tqo$j(7N?|YrOZk-%&-MRWOPG;#U2lh?kt29*bm|*=G=YD+z^8|{H8KKYn+`TJFVS*%t0I%BDzzvFuuEX$1~TqB&>2^RP;OX+uDugPPpkUTheY+I4lvEgDDc%rcnnD_KQ`t z!_O^`?#Rs>pyPHNMgH%L#Bw?uZznWNVa7UghbeR~(PKq%-&#DnYLxtc62UfZ1e{8? zW9UBm%r|niMfd=j$XVPy3-bH!EBSUwxqSsQyMlqD~DARP$tNF!9_WFq^ThD`uw?J zofA_o`D0fQC%6~vLva@Vv?L|2Df_NaVD4z^T^vf2BdDba z;l_}i6$fiySg`Ufd=DLCcP7KLI!G?k(#YVaPXJdwE5w_qmFqiV1NadER_8SG35c`8 z*~43&jo9FtCZNlb1zZ3+Ixz@Kx4*0Y+_!_FXQ@jKHc9?KvP@P$*O|-$C36t0SvPn)~aX{M9MdNGNT``jpUXd|4wGW#~Y`D?`+~}9X>-EiYD;=xM zkRNI88sqKp@@R;!NJ)k}$?aPD|NGAdTrV$H=(R!2d#-QQIds_^DxIpp-=oF;a}+>a zJiuu$X}_%NsQli?^fO|jCTY?8co^d!A>LgGymW@zuBeQ=cGmbqiL{MKb6<|mT*_Fc zU)*zjr=?@j6o8e|NhEeaNRJ)fuf6Eyoq zbo>nYGsFj%pF?d4M1xaknO6}6lkzPC)w3=kz$$e;YSvn|%= z$dYrsYsMNsKiG1fKZ54A_glD$lh5rs&tV}iS(J+Tn}NwJ z9R>>bG0JaMRJV10`rD?&B9^#;o1DGKEkYg2GhT0iXGam-q^j6yNX>^^5TR=&^i8s- zipXzNzm-!*$z%vtmfb^tSv~$kQtHh&@wDd#KI3{Pk&qJW1AzVuk zTxGa)5!Ika`^jA1YwQixck|~Ud-?MyH0jP-S)nRJG+=(OuFYZ~BxWn^#Pb~qg_zSl zriUin`k1$6X@ZdKtT=hT?vcMIkL`MO3>8(4l30Heg6F8IDk)quvYYkK|CkN2NP{G1 zBTNeCL{xuY73A0R7)aiMX`cBwDEa-`eFT5w&I??aQ6WH*O!%2hymT^o>!qs^szIj2 z5%3&pVnx7$q1Jn3DSRqN!3xQ-@!;qMDnYLs(po9p4-E#zGf5c#+MjE^uf*)jnp{2f zk6E(==&k;3@62Z^>nF!o?_fHYxd%Q1ZO;*&sz+ZRvl5RFUi=IcOMr2Yle841>7Q0V zC~x~AFUk%%*f=8$C+O=;T)>D~rr?dE^E8rsGy>kRhk?^t~Uv*bjf&Kyfr0~!%7 zED+a?!8rk|vi5${@ZRJ<nv8lsg&rKcMAI$IcC?K{o%N$JJI&7)%A+iqk@#~D+TI4N8k@}qSUYKWevW<= zE>eqXU?cfjUpVU_X)L{-ZbwzHC``(*<<}v~qtqzFsmqCltJ8mLvVn)7;@KvSCUL$V zdOcMlQ5h+i!%FAHX{}KY-|@5=C#p_d2J~ByNeM4Udf(O_Q*8V zk&JIhfx6xdLW}_V;(ZNz?R1^hz>wYXjnO%FOdxfqDclBC6z4OlL>E*`A~;+gc132n z^PUga#f@SMd7gV6GqQgwiJLglCt&sqIo3A`#uTSOm91SQ*!c|}%BbTSLTlzTgcm)~ zq}sfvTLunfwA3(my0qy-SK5X1Hck+sZZUEC2)td7<67g82h36AI3+M7 zbW$hAeF0yZWZmg+lbT{ZuJrps>$aGr$`J~^fPLat=zf!`UV(aNM%ik8?_4cvbl!-O zFN0Ck>lsF)TOAVe)3h1?RtF;jDm!QOTOox<${wadprj->Di@;8&HBofBL z=>bp`O_3=?VF4JzjbMn6^JB9`l#-Rhyl?|{sbKN1KEueef=^?P^d(_~kT-DuaLJj5 z0nC3AFOGz#u5H-n)Wo~}=|ge8-TJ6=fcENq?r(;|DALhlR}Fn*NK5S7UiPyZRYO;% z43490*CHnnGo$PE4A!l zOuRqjrVHk5oBECNaF;u4PQw{g_cN9APBIfn6cPmA#M$O*mnmU%tssa#Q7Dj+h15_W zLQGfRQBu|X$GE`|IXZaqC$La8xYS7*-e;OT3;?bdzP)K%hA_MGn+QaX)k#pB1X*i^ z8!@{8K|sF0qB)Np&jk~#Q;ljgTYbjY=X-~!7_;u;bY6d#A1n2X?4jZ)b%nuk&qO@Q z=BY0_J-L0&&IjLa8j@kurh-UH<|(-&ew#$#$u*WL`Q-a)=~wOJbg!Z=mbjcbd8Qz| z%srqnmprNIpU&`E_l{+C@G$#&@Yy)C1Sr1YzR^py@RdO~44aC8qHV*G&@}JUtkuKO zFAuAhxx_P5&r{45?%qQ2dvj+eF?m3HW~tsI!p%9)urAsD%>Q}^E6D}l41JD?;&J4L zYOVgcLvXa9@5lJ~l3l7>;8pd@yC9My0XoA&Z&gHBXRsIh!{Xq`y3xyc>hk<2@BLACI-cOy0t$Uua^0 zOHYIk=~M-^T9guA3po3RXyJ=AYSqh$Ej!zdN@S{BnV)x@z9R`@`A%=;NuGwAjs^=@ zoAWgO4*U+);(os;0BwvGcg?==V4zK>UVpEwl4OSikKr5vB*pz~qBChT01j^F0t^iX zhQx_p1|aQzX&0Y3J%U6E$R79oR`$;{;xmz!6}%v5>8xctp^Tm&TocHk*j-XL!@Jq; z-Ztt}`4Wz^7Y6Kcn&|64taxiT65Nl~>=Ylyr?L}Cg*dfpbMH%b8+3%~MZ8Xzje}#2 z{fvw5)|nkHh99YGA`eff6<<~ZGG(Jd(!6r8B>lqU$55zg^iGTTpRy_pS?V1rc?=)} zc&G6baV2OO!}g#N&_)19Y{#ULUi3Ms`%l;L)@kQaieH&*jHq~DklmG=qy|ZlP@x}Z zQ{Je3-naM5ei}7N7fG-S&S|i#DJ^=J>eUz4cIK9s&D}N8DOZ!-#SQ{;nSB6zRC~ni`qGetGnC1$#vU0p#*3?sofA$^wuYkF^+XiTgmfLGXtt3 z{hO*RkIr5{3bV^9-DMqQ=l{f5P;K^SAJ9k=q2qt-Y#3FR$+F79x|ma+pkvmKx+a%f zrrYQdJ;X9(BkTw6dFSAcanffen!^(M)E;$Y%LvLwM8|&qbRxDUJ9F$_GnZ#q!bRir zFhgEK^xB$=E~TS-6&NK9l_le(bG@*w&IiB^YVJgKsF^4;vq9tNxmx+7`nfkGdh^qB zt6(5p@&={QgBb{nfa&(g_j_gH^WCAho|919nvyouOtM$P>JxU9Dh&8O-P7`SB~I+P zLY!q8g+REEAn1n{E1>4TJ1d4dQUAMNWRykr?xz3ylx$u4Q}s-`Vo?=mT#IcWjbi{y zt5DYuAOr>BcsHAUOcfX{n%8zL54}X9OG-_aP~BJnS?gW?jpJ^En{0tw;-o2W&kA87 znY|_Za{qc|2xpHIpB~0zpj)Nys2k|e@sJxt<9lUq;~sm!Ijr`AFJFb>kh75MJe7TM zNKdosA5y3?(wt=d`@jJvJS(}i)x*~VI{Si1z zb(29hq*;EUS${z+VaUZG)=T~Epv2KA#5n+DJtNvJ!M`|f(ls(S@)&CB)tPoxxxX6P zAGaXU9AR%7h)+sZXOgGZn%jfT(9r=ExJq4%p5fJ>#XaYC79ia3mWdpxi&xM zqO8d`Hi4uyy=Dsd3=BeenCz1F9rCM08CBXOZd{*}J$cKi{a1(kg@3EYaw*W;rIv3Q zHC^$eNqF@%U3WF-NuKAkA}yfKtoQS9#HhUI;hc6KB`caj^a;3W`H(2ItofY#$PNo% z9)sQBtUpA+h7S{i9IG0sHN>>6dSr=y%rDE>%cSxitq@kk@00}cg&fG_7#GJ>NjREO z!$W=0hAulHSMJhq2G?V@yPx5tXuNn~+`pR6S^r~e*_{_QEfa_=)goBY^$QF~_lK0+ zL74SFb~i=>BX65Wu18L>iqwxf`FO@2`Rke~L*CajD>`-0yu z6pVx;*H4| z@Pm4Fn+@t~n`z-T6Uo!$eE!yNv?^oG+MFF38Ast%O0Z#)!W+NPX-t{$Hz&Y-2c)ajJYt^zu? z6A%%PJpb|lK}Ei2gn8u<*OGTofWkpbT%9sgroXb8%SR)-s@4Dq#55{ckdR#=GwwDxTu!p7LZ2wL zz3dJY5pHba+PqrGQvrXhJFXZ1WQ6GS;<0R%BmXtacY!72wkvwj+Dy93zEAp~qhN0o zxEZpSQ@l%FLEESs4G235$(W_`MZcEp>j!ft&v(r(KMIF=E zcd#NPl)-Y)Eg9puZGahCU4s$JKF$!GjWCg^#3xc2&(=3E|KZ0iCf17OlqjS$TL!IEbx87kh*LgC2;ltU@w7OKA*+F}qr=h3p?FyLhMc!>P_W~x7aJ3Jmcci!?Gp1jh;k6s^I(y_9aMd%`J=L1qBJC%IOi^9Aqxj-nwCvphD+D^L)JJlO5lQndsd=8kI5JIlf%{>U zOpAca?jtbmJC)Hr^Gc1D4HXI|>r(uNqj$*48Sl`%NMhPbBU(kc6S=<|QGMp6mVE%1 zbVum0+I_d^>BX}Y9S)NvK~P;njiou4azP83rh8odm6qugoL%odVIoTBy6pvLeGj$-ulmYVDMmE7gpn(EK6chidp9`1-q0)j*>ylBQB$IQBVDE?eE$7khW@3Bu=m z56O4;RUC5(a%UnwBR3?8!3;QRo(}f@BzfNVwkH@5P8o%>l}z`ZAbtZ!76_T8yypI` z)w!)E#K;@#z$G?EnD61+qqaQ;1_4ndRraYh>x?6%3HzMQp1Q3C1hoI$AAkT zo_D~?sVSINC@?G^9I<(*Ve@YcHqg#+?zCo~>n>?v26|{u9bdfQlIW^K`r#$; zZ(e1=l|v1GhEDx?S4Lz|CoMv^IaSsto{UaSk7&I_#H{*~VjM9;bK=j|oy%K%Xf;(%1=tn@JWGirKY`{>BHLWz8# z=-s0im(^X$GZ*odmHl>&GVB}{mB83Tf^053)zFsIE{J(oAbTNySd3rZuUhhT=VN)=BWUEKn1qH^HP0Q5Q5z5j(-G0ght-a$P}O|b0D2bfENVKs z%haA+6PJ6qh$GF2I=|&E=YA>BR?reOr9B;4E#v3}s;3o@n9&7kZ?pDP_WC7j<~1uL zgpE;CznL9i zD~Oxfn^6a_$a&?E>0a>Dt!z=O;w58~qO#6kJM~vBTK`hq#U+X||D8$@Q#Rj2{4MWd zx|+SaX&36&?9Y6x!oB_eZFWcL9GvI?xQXrP`gyoW9kNA%vd?^-r<}!l)VIATacDlb zfFHMDO|JKS*AdmZ6B)t&hULqXgB@_UUq<+1sQ};dbYp=jmVw1Y3EVWDWj8YSo%F8uX=2&m9>0AjN&^4EKyQ-I^S4 zZ-Epk56w&aZf6Vt?VUO*mq^N9)gQr4!(hnD`q5`p4tW0Ljz2(6fajZvg;alXd{~3% zHMF=c38Tsdb}yQi_;bn}yMg$bvxi2X;2Z(yjyfvuqoRZLJ4Vw0iy{dMJZ-REAn(DR zd(B?Dm9&qtZcY_ocnInKSmR4MRd!TD6>?m}U~2!r(KtO-6TJ(J%F6igVb}1JHX7R1 zR|d^)CFJUn2sO@u4NrFZ9V5SBnu6E4L+B_QF5A|DRqD=rSTsW%G$MZgZpph+X^ZbZ zvvfVxBJUw{C|056;io==sx`As`>t}z(Y{bwe31W;A%}Y9utK+oYzaBpj7!Utq#e|% zCrw03YW?<19!^V>3|n`MyYJNEulXvq!WtT?vBOsX6#)I^hrorNi%6f zaBWeqWXD+^aK@+&J&!?4=HMAZ-&3%QiPyzy>2;>ewNm-nuwaTG_hM)b`6qaX6yfY$ zP5!z!^F@lKdCN6Xx-u$)`%XX3vyn-8P@(mSW8c`5h(}w^d(+9L7BUUARpMH3R2C+6$a|6G}$Wh z&>utp^VKa}lmC7y(EwjW{RI?@F|fskl1MdQXgu{x*lVMlL5Ap3_6_MjLF?YX7l{RF z@_PmL^9d6@Jezc2yk8a|3ov=}{cWFsuX(@>>Yg2Oqu9)!x6nvaFZs}CO*AVqQKWmo z9X>9?yE~?=Pnlqbw;EKqnMUWfyQFnh(qr_Zpo*74Id(DJw5m?Ki6IoQHq!zOsZ7oj z$N~g!%Sp;nWY0^sdW{os_p$;J$Dk2O)j|@$=xz3~W!iOBwX@{a#e1(+@w+wsl5=eD zNG(T!p-UgK(qa4g*0^}wh+PO9vS$p5`d=#yni-r@>!0yqaMscX}RSho|PnD)v2de8ohQ z>QELSn2tPVw=l>s7H|l{lK{Y&x2UDwANyNv&}?BVuDW{1W$KLM^8Px}-T-_io7Ws% z*FEL=VER{&IC4yeX4Iw**a+5pAS;Uzx8`(^z&!q39XK=MBp|9h z;0c_={wqwEnzSF8_O#`E_7$3{MU;>F;@@A&BQo>9lzX^w$imO5U{MBm)cVmhbChU& zgg%xjKyM$DZm7i`S6I84sQoe4|>t164W^KY%#amVUX&(-kG0pr5g@Dua{w-%uKK8zAIxAg0ey6Ol0s z_S6Vub->u@lNRU0au<6Y^{8(X=He3Sp?AfdE%_ypiVrS3@eGiSY@|a3A?IE7kkK;g z>{RXIt!SpKF#O4czfn?$@~)yZ2^J>|b$&G*`~S(tUN`%Df9LNLZWi-NqR_2=w;1YN z6BlQ_XGcA+4c|OO69)cO>gQ|X-dDD-uaN}4&v_`uqDl+T zeo~xUr~#aiVCCvsa&EsII^Z`Ts%5=#C2_F}J+u#fNm8r@J7e|69e$7jmz24|>QsbQty=*zBHW zmiZLXYL9bX0D+}Z@BRQsN!6(i7`&|Vviy{Hs?Oih7us>CU5>C&0l{lZ9m>8c@UdND z_Ok%t)wv@-pX|FaV#S<{drTBh&D0qP3OqM^bF#}Y&*^|*O9ZmYjcLog0rdysu_d<| zcJxk@!gQt~S^rPmkoRhr9F>(`*!Q7WrCG&<&THmVO(ElbBI@AqB>H+S?jY>eZ&xTi z4(xY6sgTx^^zRi3>r_Y(I`AvEH`5Q#kE^kQpyzFgfIf-ZEe{m7(40>TP-f9k?wCIB zjwro&p&Pep|Kq0gDjnqb~$9Y{_h`^q-?y8%yh)o|kgq~O~!luQMy04R1Y8Dj_KVT|z2NVz1Y~>%tc6RmtVA%tsT(X&*t^$E!d0A0H z|IB?ptM6|+p*z=*Ll@o+;zPy50t5*2>bX45bO~8SK%$W7LzSs5C?TK;WdRo$76n&3ZnA?%B;@tl03fQg-q)fOr6V zCIRwPc!F%15zQ(n1n`CT^6DDIr)B*sp2oTGl{(^YrF_E#S(c~MRf0=Jftp$(jo86Z;ml9!DqZtGV8xF!Q^v2r2JR1Hqg zsoka}_FKpyU>PvtJaJMilMnQ{qP@?5Er3)J(|=)4XfaT0)_*CbO1(xWJdpfo5hL<> z`JHe}b|udg^{3PmRsGy$f{O4MA$MBm@WJNT*CYBSWEBrB%FF;93fedFyxUEv7k~BK zIAiu?v?E7SHf$nfA(b+|`;;og3b!jfa)5K1mV5Y5FVlnepZNO8+qHydTg8v-SFreUfKT|OKlG{s{;tO=TL=*lu7z4pLmRhOPKMHe94O) zr``Hp{SLjLsn%>COx=xY^Yi9E4m^~D>kpKYQ2m$r@DXxGEK}Q(n@1jeF_x~ zAB?JdIJus|TYCg@?~6&pPhA9Q`c$Av&yC?N2RZcW?J26avf1U@%1Qm4f&7K_60^1*Q%8UUkT;t~ z6}SgueWC*>m?NxUor0%uJ-_=dK(SpbQ7f1r5PIO8W*1~a8P!z7Uh^TbyDaqwudQFF zb60n94$v|cEOm6vx}yZ=D%tf?-D&AijxUK^pQ4vY7LgS>fd49 z?C&I5q2+VCYzbQM72eAq4Oqkptu==r?Y~|DXT9;QOLkV#9_>aCr?WpF6duEIBn|ohSU=r-K5|!Asfq?oj44y$`0dQ^B zqPwGUhn!qlYJQ!#kJ?$RxW(PM1ESBT{B!^IfZ_p?sZDWrV7*_z*oG6Qe6}^l?ScS+ zl>y!j`0m~Uj~>mrWJKXIyZ~ZxS1udf zLe>-mK{Ti=DPq!*hxkItZ9-oCuwaA`VA$U#z~g!W+bV4sIQcdiIQh5dCk#doCDxSr z()89LXQ#GI%e|bFF@oj?PevvsU36VrbODTI>j4B(6(#v@{9L&mtAH@=A>1}BnCz9Q zm}Yh!a#e3ZsD_kxDOPR4-KE;|ePd%I%|u7y3IIP;`7~?JYD`W6AcNk-q8N~z9qVcm zbGWdbyiU>c3l0!~31*tn-+bdq>JH92G;{F+gz$}#9C5x1xMvcXnwYl0RzV_DzfKv$hAZ#QTK2hEbzthP4KQdWi)&m$wVj6__+L(JG@3Tb^(!)PWrsZwq zb&G=SPRxJc=-OVS1y0s_yEH(8yc6By|wu{Gz)VV72;XdkIRf3^`@26{!$o@hjUQF0172HfG_LWrO`_#;_=8g00_S`1JBlcDN^r2?%xy~DDSL&7@d1{HSDU@#(QUgmR?Fn4-H z&(^Kkw#}I*-59H2ShD}GZp7Ep%iPI35t*>rze@$8^FEiqsIQ6wuCMyy+R3uMjo9%Q z7QD(B=$4(G78>3GR-0i8#BPwmn=x$jySriytiggdeXh*|OZXj6XfO4j(~~Z+699>< zKHq8^i&$dFgvy}fM#qoA@;$ondTy-1;O^NTWh|j<;B=At)-|O+WPZ`ADolS%Bl$M^ zsvG1C+efkZ+ZoPtY9n^O%`Wo{;01g2H6sZCbb=^}M)7bFd*QFYJ&0*46AU3{_~}(} z*szNhCi9z@mffX;dgt2JbOA+SWf{gKtjPJ&+BEO0u}vjzvNM^7@!yh!ap!Z&5hk`h z$A*?y419M%-{Q$ca&=2$4fL?aM$AfIL-0rQ;cP5)_M;Z%SlU2ThOm!?RSIUYJq&wm z34=x_zv=r(M1_y^FfnW$dc>eJ8Jjvk1jfMY5eqElrQLJ0S}Eo9dSH*Ka;i8pYY3lC zzD6abi5K33MgEAIGK<|bt$2txXi+^OfE|qT$sDl9K&`ks55&5+ms6B$#OT$7@knG_ zy2yBlZe4<@f4KiKrmWHQbPNy>h40SPN3*d~T#Eq`EoqPrSR3#zA2jjvn9Y!C%4Wvu z`bOwafm|r3WOF>jLF(G5v4y9oH_K$aJ>EEK@I#75tF8E9pI5r7W|O}u>{`~&GcAD_ z&mgpW>Q?HV#iD|Q$3wer(D7_(YiMGgj`Wt05AhFt^3Rafjnz_2H}qrDBxlQJP`eJ! zP~+d}$R61kZ6=4jC!ykyFIs}qGix5&A}Dt*$mxJ>6tUC-0HPSjW~hVTM_arZ|y*B$CYRx=B1mUzUS2sg;bs-r;?2?gAkX)9zX zS^RoWjgEb*2IjkXMf5ufcS2g*>S&7ZntA@fUCLGwhQ02vGX&7Wsl}V5M#My*&9fv^ zu|@4riF%jaKs~CB1PCj_O4M+jWR!o>tY^iWuWkg>R)oG{&=th<5Bx~~of`(r`vy^q z7wl+JVRnzimo}AuVYF0-yt&zvrISPyWLiaS{5Wv)=yxSHx6LKIW>-w|`6BJm_RpvO zBs`V#})3CfOV>_&Mswy74=8j|h$y(_yujWBa@Mey`!~l|a5Mo_1OH zn;^2rB^FAt@5qWOojy=&%Yl6{>oQasTrq%V%Bp?N`TX`8RL-0N zPpd=`W85!F9pz}1jN)$05STC&rO>m%`S1!5mNs@dGF|C_$8LmG(pGfHgvcG0W|hBd z!Jxg7L_uY%&K{)_OL7Jn@PD5=7PDg&<3ye+@NIzWC{Bkh^CZZ`v$~I`H#z3i&*@KN zA_E4ttbBK3(F>Hy!x9ax>h-hUgx4UCesTN0emUE9c-BVea9TO><+n7|af_`_sm1C) zv~lj+Fa(91f|n$lVXP+pYp79^<=_Cus;8lNS;_j0xtw)|`F$kBo+2pS%?Z~qAzpD(XuO#b=39jZ0%I8$keEe8!JBMAP*2rKf1 zNXDDYb;N3NYb)U_ZNnVpAz|y|p`@_VHDDO>pV2iVSc&H3$N#>KcH6lN#wsWXA3c0~ zGE(6}q>S*u-stQbQm4`S5od?a_J5{Tnwmpl1GK@u3znl^mp({+(?At&lR%-YR%7;g ztsAzU8`S@V0B%{f%RQ%`sw@q7;MGKhKMA}VKy|@KF0pm8XTZ&R{QwiUM!ayw6a$I3 zsO-5+t-bkuF6jFD!^1N$r3v6iAv%&~fJTJr#@QDcw%2nQ2lFCS5W_SIbTD)Pi)N4> zg|1??2LEHV*iJ({m>tq$x|reT=Sew~hJ-mxG$hWA5+93xk0;~iQUoX4UdmWS{=q&= zUS{?+V^iAsrF9RxNgV$x)u3^VOuaWA9gMozgC4??_39_!Q1#Fe-fw_ zglcFVNZP+6t)bLuAsqOaQAb;xyH&AiZbbB2cOjsbQEhEtsy8e$h}5!7ZNLD$tBeDC z=&5~VlcX_7@KPJKRBsH3C1;GISDsU1?ac`ru(Bqu2x%*_T%oJ#@NAqO&a6yS_%S0; zold3N40t;E0B1)aV2eQ9vuo=1^p*~mVJ7){Hy`2;qi_%qhebL53BH?q6o)h&vJK0( zXYG0E%Jzbi&?NQz@z3CtS$CLOCgB_|qdI8usEFwy8FrK%{e>0)lD~0lOsr7QYplO(gPjvJ4;1zjbX#9`L2Lab0ekx@w9B3h_;5V)w5l9X7z#Afz*~&f)skFHD6owk}cSP*1d{>Q-Dyn*{+NnA3)wqZWz6Fdm&(MUgcnV#;1(W}V0pD<Awc2(4z)oTr)7MS$HRW^M z22{s7U~J)a07Fk~?w4>3u@RfZT(ukRjEIIjNu-9x8?S$8P10F z|1n8}3w;7qdWzzyZ>C-E$zs?=_^cvxl=4jmv`d9|MjZ$)r@FrRx}iX7Twlaie#`1{ z+~gSEy&+4#7+6~ujc&SEl)KBF1ULUHwG zYQbNj@H@Ozbks&m;)F2~Do3tf?Wt=PehaLVvsDoOnU^1cf&)IjFi@rQbt?WQ-Qb3i zZy(#|;GT`fvlEt;g#fzLA5;*`5u8U5Xua*oIBG3SQ*S&#a6_Dm>EQsE|T5X7`Cm?ta+9 zG;7(sq@A--oy6VH%NpVY7;i^4-s@~iUamioPSWikvMT5=& zu!8@G;xc2+=oe#Rl;|guE$o{M);v90o6G&*@fmI{;Y56lIqQJ4P{jlD-Y~=CGJ`!J zs;I${*W>X{KLpE5Tj9P+HH%P<{_K|tw{+r&7uG{E5iEzy(|-J#RHNQJ&9{4rqwgJB zPf0y-dLac>j07c!DeRE#8QG^nh2xXVmWddeDe)CXpN!TaOpv2r9Hed?-Dkj)_L%!@f|xAZFm*UPSra+MOd0 zx&V|#znsF56R&;!asPs}L~STzSKl=9ok;2?eE{B9^Cfq11@A0bY~jj!T>}q>)BE5D zejrLDs1#!v9ifLfG}$&s`AQEdv2Qgn;y6R2A1=~cg{3;g*ZRY887i0qZ}0E^xq<5t zIOR1LfpupP=QV8p{q1pyw|B23fo~_f#{`s{RASn;al|d+)X^^Gj)Cteh^pWmk_mPu z4YE_LiB~fkt+oFQj{HEIbdZbednnvLzFRMDa{PJnsl=v8D}_TL+0tMNQ?{&^1dW1HB%XXS9 zTi7)s0uV+lEo2cdV zFcjRDzI+K`Va6D>8ph_|){VkfcIuA?AsnnWJ?+V#kAAsq@)Q~~kcIKl6$ihsmP!&I z9H1`hAja_U46p)--b`3EV<8{NEf$Gri+wK#Nl;XsR8*?|MePEVLrB7e@GP?#ua)?J z96lAA&??jC9=VkT+g;I}OI~Az#k9(ESm`++C$nf_!&qiU2#b(e&m)orrdK$P!ND4N z9tGY4*URlz`<+$=gW(jLV-15*-WBW{%tww$-U&C()>8PStI#FM*kqMW0IKGh;(BtK zkvE|^JP<&a25#Lv$ON-f1hhUQ^YVsjbrBdYqT!2MNOV`Us7mdMFVdZ1qvPv0?Bh-tfb8~~y}}yNk;_)$$M$II*Pm42zph7bXD5v=<(g~Z%V{=!KtP%$g4%YBH8|IT zV-zqBz6y_39ZY?afEmfnp;&cj)X2(8I$s=+VT$wwcOXg5zR$ki3`a$sh;r6eXyx`!VzNe zh+zX{Zc?2*7IMj~&APRu>}?oXZvNiG5`t;_#HtRUN8HU~n#Y`jlVOe^JTd9^da6c^ z?mPWpRP5Uw2(M#wQNQpqFZ(Yr>AyYUphQeV3Y}$UtSiQ5h&(T(3muos{S665s^LKM zY`yizYC+veR7ZEn?yB%lryE&4RKVTSkO7vDTIx~egm%P(V;1)ua+%TMP^w!k-tIa9 z9X?!su#?E{T^&G;gNI$S-OhVWtbwvIgw`0rF}uC>fjCXr%SM@0?{r%Cd=xBg|3Y?F(tqgkx1$i|i6F2-Aq~z>=l*+D_Ll1yH6$2be zsp*~-loW&g(R6`cZC7*3V<$9R#-$oFl>^xs~4cMT#fl#^@_> z=#IHT9E|+tO}Q3_S|XtF+8F4-qk|L4GJG6l0j*6L`W=8sKhVA{g7S|~7hCjC%O^*t zer7X^xQ9pwdt}^=MsXmnj#gL)q1LqWYNzPN_?deS&dDi3cyZ&z<#(f1r=(Y@1r8>4wf(PPpf1>`k<)q!e9bP&QD4FyBGk+9 z#~KiiBr`-p1~P28CARQ1@y%LBQRW)vfA^csK}gXh-Jl55xmsYi=(LdjAUs?my=MJf zX}oj^397g&%1ofcKP~f0sD9VhXTDh^C`}27AWLUzpVPgBIk+x#!}&2p-s5Kgjw)89 zyW}YakHE1;C>_Gml{@=?=BBkOVvL%w7BD{sw|}a+f|T-^y+yOZSQioy78zEKS(AV) zGVh`|jHwDZaC7zTM!uU@gw!zDm;p=YnW%AU;22sR9U|oS-oR=EwTiZv#lwamLX-?Wn%Q7`GOUWgRh7erhf} zluolscc*l84RWU{zV-6>>ieQwOe>a{5^$vaQvo|qtIq(fH75e5z|W(nwI-WO;N zz=?jp&(_TrMQCgRN!p7KM(IFVp`jbmTZA*e@-TmnosV77tC?Lb&p3l&0x*9+@|sd| zi3!ep*Wrxr;N|qyCZN>uHSmN7|G~iJsN_wPmLk4{6w{DjVFoAs7`9DswTH%^ETOz0Wz=Cc-6xC(4}R!ep}}EqZ+D+ zdrF9pZqa}dZfGh_b&YDeV-gyobgMv>dc|qS5eL&}?T0Y~0G*aVk4ozPjup%jI0_5*I zFv!7#3PR9(23yKoF5!|02|6&FLuK1*(`otlw#6h_Gh8kI6}xvYSat#LT!4$+v^Ng` zsKHZVZO4KUsj+uK$Mferbr;S}uxzq;1<19YkuP3zgwZ)maZLceTOE#5cI+J@+9trEFl&j6vk<5 zi`UjrS!aG*g!Cwijy<%mrh|3M{)s9|DD&`bpHZJOJgs*pqNE(k|)VJbj%Qra#_1P9e_*?!?Cd7phv>8 zhx^bv50}n@jRF&bZw7!+8sOuWB-VGl`;@Ro>{eA8Ti!HT{OC(FpCmtIJ!0P_;y<|T zzELVZOW2G-ONATG2;%m2QiGd8M}ixH>8+U`oCFQUhg>>DWp`N{Qb7TU2J>Iy7gJRD zzwW&(JKb(>ib=JBM&-Ez*FAW(nXC1WAhPyH$*W)jH3UKrpnqfV&eRcFl)ee#o? zBNdv+Z=8EU(E8FbHplN^G(xPBy{mn`S@_!T)+qK58XLB?x4{OwYhbrL;Pa0@J2O2) z|GtD>e1Sm_wpe?;A#s{Jz*?sY_vCqRpZ8GHplfqt{5wfEQsl+=$f-vrozj?fDj@k# zD_90IOkp!}KJ#_>^W)`sVEMnQgmjZ}_VPMOO4-@$KTRWp&$bid_uY!=mThMEX~QwF zk@1sAX2S4H|2XsuC7)e-xgEF>SyW>!mCC&WCVz4yAo)l|;S`LC#@xki+oyFg@)2Tx z7?N`gY*4lm76wJp8@?~w$trtlXZ8cNN z)6{Jn3_{jrqMy74J?w&_3Lw`%Dr2sBzxWokgSOsCb!^_K*g5Mu?@XB@THa%k8(RWG z0#pU!P+#T2g$H9DK-O~GJ@03SD3o^d#|IfPQd?mhA)-M`BWYu?{j2p#R#r~N7@;JU zpwRc^g2@~*3(fy&P4f;CE3T?NTGXG2XDfOJg4wiE{uq-=xbHrZo!PbZxwwuvzMR-d zcTLb{eZM7lhxJ_}z<%iR(*V-LVFwM!9knyjVf|{n;pAX4*3{g_4T3WK*1Orj)8ce~ zNw`6VLn3IuswUP^uPy=_236^zt$zGd=Ydm_LC){Bo~pAKBo?~!6`iXF`G?wl)gq#DS}~#8lFKn1v8qCnM7~hZtEKM2?chz zW)gm)I|VS@^qbp6asnVdV9>{|ZLV8_q#(O$vo>~gepAQqd&>q?+>d!^{cpVf;|<70 z*sCur_!Uzw-rj;qUvo{>a4g(LbY*`PNCS*|5$~U@$f|$0$(|079xf6=4>Xmb zMKQn9o%~=(S=C<)_NR1}{?$#L4PLfX-_Tv0EVz2T18U;fXt%iKQG*TrJZ*HoX*gT8 zCVMLQbLNSobVQs(eZgVu&MRm-^CcsK2xDrDrQzzNg|5@yXIWO85GSnkesWCU<{n&V zT{ds^3vDiiEEx67bRZOayNF=$&HQ(H}i9FW|>?1PQ`pituVaE~? zh0#-u(!@jis7|aBd1Y?z*Vcc_-T1^}vC_Qe8=Q1I-x>vQAtAEz1=CU(Reh3q5%O*X zTR9Z2>#zX-DB8-0M7Q4Sp40DbR%Mye>}=2Ep)3M8q8lpP;G(?KGa_p0;LyQC>~9Ps zIqQyf&P8y4t5SsjEX`vdJ{HjBlclbb4C4S4Z^ zQC;csCam{utAM_IFR-tnYdtERT1PLR;bG_w_Q&Wg4>TB<@yu|nfY-C1jepprz7=%|S7{r7+=m4a=N|F9^T&1{YwCnaN#AWX0D)iN z?6xJTM(A9t!#p@!_$9h@sB;prZZ-h`*~}A+I(0f~h}7Tcvo>>rmJQ5iIEy%MnWWPT zvY3EHPKXo*KwNZ;vV2@Iun9Rk&Y3mA>X;qdl;rQBCDH9kW!i!Z=9XBcH!h*S0hsLO zkC5x&ngV9zU+aJh*VCMt;FE;GjN?|11e|^0mK|baOd|e_l_mu1=vO<9W%P9^>~14r zkBj?WUUiXeY>>er?Uc7##hVoXg(r;$nE*jRzQ267#31etictuM?g&55osJabQd@>Q z6L@F{`Kw(tEIdu_sKv-~!0UfbNDc9;byM1trfp*J<$py3l;0k=%S!D~HQxM#PJMo8 z3y+DO_LhDyN}lWTFR@<3o>AC)@}XNln)p%B5bU<>rITDQ%p9qdm!&u%V=jwrOUB40 z4umE;s7^3r_=svEnq>K8Suf*{$We%&sTL|rcwc)cXxe6+k9e7pWZWR`DuR5G3LDS50#c0i1n9jzCz0T5knW#q|Uax5)HM`&2#b&b(fPHI+@ zE1du2GeE=mfg{yrXQFS?@y}MzOLFRl*q>#jJfqv6Fea5LU~g&{${s^&hW4~_#AS5p zAU-|$D|nv{R{|VUR#@kC4u*GisODHXew%QTZVi*}TfI$Nhk=NP{NBU1tx}!Rs?H@g z<3Tz{IJMQ0nT_(?AAY~Z(J8{}?5Kaz#wk?KAE0u)VqkCCp(24^E`bxlqR-il_Z z&(j@YA8C(W#0dSv+z|?JnJ9l&+RHVoc-hhJc?{V~W{?L0tB`yy(~)MU`2;B`^a1Z_ zcK_9iRWD5-I6=O5O7{!HL%vmk!%lW<6E1Z=Wq|I~uv7W{vxK}z=o-!s+RHR}EMU^E zMvi~dptbxYDdKYX*wQwSwU`Ie%v7)~<-nQ8<^Po5Y^#xw@3{JXL5CdrAn*F9_F|PN zH5^mi7;7{y@a!KUke*vo0j%wqcGU*|j9!F$>z~Od@WUr~V1q4dtO%r|*flKgHcY=UxU@c@X9WF zJkWx~W@hpPm8BsGjI8vR8L>2pofmqA*&ZA{@(y!j{4U!4n-~^=X?aZx;zJ zM@dtV2+tUb^TAGnLW6p^>Kta=O%$S*KVT8)ez%$3U)=++RX9Ze>LyoJFKw8_n2MHa zLn!R0Ox82xTd@aFkgShpvvDt~c+{agNh0sIp`}3npps~YQ&Y5@$Lli-p%6oH#`hQz z^aUXP?-Wyh=U9{&xJe5}<6!=GPe$NNxV;HSCDq=kTogg{1Mj)`UydhFlcihKg(<9f z)Vcu2gq|z1tm0VFX3cn}stSDzygvmkcqS{QfxjORt|L0x^;}4|~XQxvo z;KHC@q@52$+515Hwv+anUNjHCR(FHX2QU4BUNyep zEQ;y#85c4ctddY`kwkF<_t62lnW1kaIZoIufWA+Kgo;JX=!SD45Q>%KjB4oY ze4t2bWE7h3afaW|8>#pLk6s=HsHt2AT^i?se z)<(qa0|gdo_KiMd2h^oIlk?4LcTE#m>1Z{g5CO_ID{u}AscH!VTm&ks!0m(O;ldl5 z-*4a-&Xwg@Aff~x4Rkziv0i<0us8EqU`z~iLB%Sq^i3uAp?Kj~)ypj4hZ3}f0{Egf z?Dv2>PSC4l#x*7dyfsKXjonXh9h1i0M*FSyAwyd$ts!$&pO>+Bwf#D z+S_x0_ha)mT1H8OPk`fu>Lxvmpj|OUw+&hKd@FAYliares5)agdV4Y@5$W2@8(3UEycSRt z;#jl~3v^$w{hDqfT5zp=cr?VKUtP3+LMsr|{SvUfJyMxrecAQSRn_w>lIuGO)NP4E zESijurbBObL;1UAV<&!1XXwaJT3ICy%275ZG9TH_eyEC2k(^eSPZ;9@#nAaBKi7`8 zb_eoToUSjQiYX=$syf*XmLFMESZ-zhe`m3h>mJpB=cYszH#o{_Bbra04TZ>jf9+!? zE<0B)_GclsDR0eNg&{}$d;2dKmaSP#Y>(+(Z`$8lsU1njNPJ@QVKVb=sHSu};8?}i z4#Q(DW2iR+HFSw|iv5WrojT992R$PsqUSl2bSRDjCUMnyhk@u;0ekkYT zp!4RRmKHmi?~jAi$c@<4%o(-%sm<`f;@_HGQ<`YUpQy1h6JNB;e9AKO34R!1o?>;~;OJt{KMUqn)PX$PGf(aBI{Cy@R__NNpB zn05i_fal>&9#LVALIhj>-`14;iRdDM@F<$Utf~rTephVDP5ZpB`aKd;YXtMuNr9tY z5f5(Hy7G%~muhy8V?}8j;1)Ijrlt&h)S1qcmrzqpM?OmGy3p3G#eMK-tGH5`*>`KAjn@8NF?_e7kA8FekQn4aBSd$@3>P+NvLERS>%*&@5|43OQiWs?pS-)G*ChA!1zgrk-ZF#=xmvD;>1%}3> ze+f6r_o~nUgFSex&I)g~PtZnHG(Q7604{A|ZW1Jbm+YU1nUHwkjH<&N&qnNZKI>}M z=5dtad!!Y=DLl>|Coj96G*QOCLti$++8@m!!Cd;EQ~tPMkF2ExGTSbNVI2^ho=jw4 zmVn?2xswD%vcu}Dz}A)rCDZz|8QWw8PV`TasBBXl3M8`9HTfEL%T@=OY z^7Lb-qhFu>kTO`LzkzwhrkDpz!gPKvS6wtkmUTexJz_s?M_a7t*VG)~+6k^(*2x~} z1#o)?$8ZYY=ZN4g8oeHonUdAB$Q0;%*;x7sRUh-71%FoUB0S!H00KA5`113+1U>re zeWvw(iXrAA?UgJ%S`peg*PHY-mm!D(#PgAd7(nBtX#bK#)5rQKv zr|aHUNKYzvHuYt{h`&i?8naNHbg5MMi%qqd;E0d8;q$HVlC_G%dua;gkpN&;3D2La20 zU2u~IhE-!|k@)!b02#n+;WvBnK|h*Qmx#DV9bUCMdO<`x^+!IIQQ;^2xx*u{WNfb# z$%cYhE_8XIqVBrmLAKambpUme+j}7}Nkxcebi8hvXw~);%up^?+aL#5wTt}myv$I( z3<$QHDmSjtLKia2jl1xAF$7MII&|$Bu&zk*w|KUjN(0d#Z-Bix5@k6-+tCAmjLOCl z{Y<__Wk|c7Ey2jyyYA?#YUZJi3ItjDA?P-;F9XZ|tv^+`2}LvbDk@~_z@Odej0y(w zs17bJCOYCna6Q8A6Mkg#`&VQox!T;Qg^L-_(3@}*WR7g<8`(|?xW2S#cG9kxEeimA z0eP8Q3nU{kS|5v&Vn6?3D*6cgAz;Q6O*bXFb*+eu1{HX`fg8nGh2fMu>0h zBx&K%c33^EeWE_#;I|i1C~}KYJDViprfHlF!0;yv zi_U({`qIR-&SRb6)P!}s(@qN6LG4WZ_)tC8hg@vE8qTsPz5C?--3;=yhZi=n^EG>b z1+Bj@E=NgfEgt-9@q47-sr1Kw(EmdVF2c%sJAb9L$i6Ce+?wg;)ku1t@8$KmDq5Z| zb!T7~e_JW!SV=CAJo3vt6}UpRdl%`bz!QO;1y`xocp9#l9t>Q6}1GIrqO*l+$failVup^v{`$185#{Fh;u}_HP zca1c=G_@r60v>Ky^-OH#m?NBmCNY5!onDhwwbKCbL0_{K^5|st_6ri=^7ipz^?F8Q zxNVM&LfmMilbvlHP!(S}gt{B(8ISMlR++;AxkSafRYH(_*G&^{;E9fl?-1}fS)r>` zDGApp#k4#cV4-AN2w?%xLk@sSJ_rP?b~yEEVwds(Q1PW*k))}Vi>O;2=CcHXj9Fwm zNO-$h2b_AY;wyORT=)%+J-!tKpj>hp#+^T6sFV{C9KkV5r-%T9R<9=UoUZan$oQ#$ zFI!`3L?=v=6&tTMxswJFB)}IBoch8!OEY|hMON;-`rAH^XH88gB#tQVtaH-(7XQIY zQEjAb6#%0!7}B>T{V1YL8vlj@RS}e~H zw4r%~I3-n)Kd}~G%-D6+qTZU?jd6wJb{(&TG>WrZ+eCT|NqgNCpGrpk&M;1>Z1?D0 zVb3t{73n~Yj+f=T+>M_S*b zE>S<J z#S6e=#E)Z%_OPQ(ZNxsvM_zb9>}rmwJ-BiG! z*H5$uNxvP9Jk-Xftea?MC&G~6PBIl(Qg+L9-Uf?M@IiRJVeMjXvPIR*7$xhg?*6g8 zD*oV2uASlb+g+sa2SS?;^uj^H{%zw;wjS1uU#{BT)78S2Tq&zzsZ1}~rPAVkH|q5$ z*tUu6Y8RC$i5}*A8w>+pluU2JOHwVUTy?DQ#%Haulw{+sIeApF*QaEVW-PaDexPRS z*WiE`Y5P&wL3yntwz@CXcFxM^nvXA}OE{8tAY`{nrkCpuYwJi$D`p`NOebsm*~A{h ztY+OW6Xl7K2|%h!Fzv+MNxTnW_!wNFaVHK#HN6_D%M8H)37Y@UuF;!9hOYtMB{dOi z<|u&Svec2YhxP;CxV4c6gvqPY>>t0 z6Ql16(&6wcm5U0{^-= zn;s5Q7YvQ|M3_RiJ6&c3UAGNZSget}M?ubSCoXO*Vh`u{XNPP#*)rs$p?N5QHW*l6 zcs~=KT;`1_7b3PmXSJe&*g^7$^aOCcEpJTELGCkSAw!6+PDeC^*g*5H`fscemdM8D zwmzYYttQb54w~k7tA;KY5bqbO4-VvAN6P^=EPa`0UEx_@^SE*101joHR%{bmr}o(? z@q*X#_lE^+a>DGrsaFpSZX_!34^O${WER)-f3GpW(nS1#VoaZ^>(P=;rMJkmVyK1b zkK7F8aiC(ss1E=FzPDi1E&DPBPY$|w&MaH8dYUb_3+#>*mKvwELmKi2(A2ZyU6U>x z^Py%x`kRJ{1qwqj-^h7wjoWFBK#%=QHL3+~<@&Z+)?_^ptGH<+5#VDY_af2NTdq$8 zq8difF<`idBngo#qvFSIq#$lGh41{i5qyGFa9!g7X^yroakNV^9g5U53n!qz|H8Iv zcePmXQ5suoM_BIwJv7I=cldaP$Mk*%>=%t>0s`)u?x*{y0ut-~&6l3@%{BQZojiBn zIaL+q={TE0Y$|%flq=9Re)FShI)ej|=!AH?fUECNCAAT2Q{h{v3!!oJ5Z1TeSZVV! zQjdsmF0EexTyhHxmYl^r!tFK$ay!=wHhjHj7z>K0jsi_A(|H+y^%ee3ljA0x*`06Ltexm2M0_5{bmd zthhR2OF>mZvzt`a~l9mpSo^&0{$ zHgKloP_dtc8ik!(3@;GsXW`YJx@_P;Gti5P_mP`bd9E2jji#huZd;4j6dcpFC1G*O ze~xE^^>|mv9p+01T+a!hl~zX;+iX6d$f;FI6uTblX%2|(2M{a5tK)PiXDW`M8|Hpl zqTPv3w$6Ua%DrzCc^Cq5P~dV(8c-cr(CuN@ct^z2?eV1;TLtZV`Hi7Q{ zy9(TF)j?I!Ofc{rKm%f2?o%Eg#&eavsln>i?R;#KO`bb$@a=L}P;K=2rI$Bp3t%xh zU*%bo32BuRX?y`W_LU<0X=r4hfc#52*Z0=vot&vCq|H67Nel(|q+ zf?sJYG1HV;?bgVc0(NkOcLF3`99t&68Dnn#<@_Gy?AfzTYJ?vW^Kz+7!*DgYpfGo_ z<-uY;&c!z+f)J_^yzAa07?|CSCmiX(ecfsYXeak_62i=pp~AdwmVIEBGhsNvsr95o zF`gnx(-5^wnrVTZPGb-gezA!B=8F92Jc|9Ivokz`mo&&)8CD~K0~znZ&Y)!n(Q^MH zH;t`)pScIcSG1ZJGaLhSQf#DPF4ZAk1CVyf)HDK5&}eM5O!AH~ zK-l(MM_f|7Rm=9_`_vLK7aF@n>rC9@_|}LY%b#F}yPZF1TaR+KMF7wYv;41gq;t** z+oC_?=We1mJx{m3A1ZrxyC$|mGz+T2v-B!M?k^?N)CX7lQlmI=ji+FJ$7x_U-2O(s zIKw3^3%^KxTW=W#S(dU(rITSUL>CzzDBK<=FK;cw!VM8@06;bNH-;*8c~2lzN5yC9 z@zAu4s6Jz^NE~#OkoJDzz;-0<8*cwQ^7V%vx`DvTvu(rivrmPT3fzE;;BjT7`my?35=~ML**y8c&*~U)88EgJ+Bi{Hq{wNN6sVG+dp#~$s>~JN@a1SnUqooPBEMg;z!}Asi6*Rt$T%Axq6qEookr1Ntqhdfv1@*X6%s`AZcd@wi}-!8~PgcMFosil@S zA);i2Q-h?;?mwb@@hPSDWA$C#3+zB98~$s~a1Py>jDsT+N<2|5L^~%ynKE?Uelo!V zU(*iB3+BKfKgpK5e>?4%PxiCw|BO6-N$r;52dyHt3gx;S+eN0|Se@=?>{NYwH-%Vp zCl*`;ge4gYj1DeT`GF{vobYF`Z0Nsl%negL67DjiaJW&Ni|jfIFUdvOaP4InN0|)> zhN4b+`{PWEgS`);1scEWZa|R{@d`*afs`Qd#-mIXkLHj${$>a?lwj-YG6M{erlpJ| zHjjR<2-*BoV03+5D*@B+6UckuvZ=0uI`N#ghpat|fj~NbVLKoG6>R9l!wbuf1a4Q8 z06j7U*&3v;VealmTf|{v?z$mHroQx^rb*B0KwI*-Sx9+q^V*i?ipunmMV*>ym~j36 z#@r$56L6?(ZTSd(#Nd#sA-A<4ZU3B(Gf?~N4ND9zWHPGE#_j_+B$Q{=$xuT3$=5;=F);*RSQ{3$&LlR~4A zQrV0CfVdpZbX@J_89%w1I{Fn<(+2&KCG@N7+L=wwcr1-CKtB)2#DU&b z6*1ly&_a79Wgd;twd`uWA+JpE9#3DKNPPSLELb%s_{f0D^QCfddn7(2Wj z3*gG!MBsqh<-Y27F5T7+gLG%|9iDaI$a3q`{%QV1PsBjYeE|06n}pV&``KiZ@oISo zm3+C|VLaEFAOcE*sdAzOwmX^n@fpeqGlD*bG+Qd9m^s*Y<&;On5_js};ixnGTKf&8 zuQL6QG?~_&(E2DrdRZ3u8fS!SNAmKkUKCo(%*rZ+LUk$672jw<(}Wt0(-%<~AOT@u zr~KXA%jXP4<18S$nl~7&e|Js=gj&RKLY5FIh^hJ{11drTrTE#-3D=FoV&SQpYUib# zw&XN;t6aCh|08?{)WYMFf93~ae)&F2_jdMZul7y{9Mj&8uTc6+;(TwQ&{XEdgT2A8 z0Rll`TPFykOj^Hk1M$8C&!bgpB;eo^GLP>ZhmRB_#b&Da-^tfY-IXhrW<(;E*rACL zz5C0KkKHojTRqf#MM`%Q$=2HT`PN%j2CdE{1JUDUyJKf7cSlOpJ6Krd!pB_2?z?(d zjCgv7M~p+Nag^~D$#1vC1<1eU#TT0tsd z=$AL+N+`(M<4_5?QR$E^<4`1(!DU_i%9j3vt|olRpM!?}-0ktXsSLi2IFOhEVhP`j zu>0YLz}T$k1USP|*W#&63szP5FYG_4_;dPM0=LqF6=D*8t56WNtUs}n;!Vu>oB+6| zPDv^AyagU=qI8YS0UH+Rw&NK>_?np8XXO)x*%q=Y=@2M1hStL_|5mOg@J4Dcx`zSo z*ivJYvs-* zXE<^!Me+L>ks%~4$_11A4+f$0XHf@%CbU~KCf&$>A~7JfA6KbZJ6B6NtF?a}I9zii z^yF4Ns!UrucPDJees0uR3t{jW>VD(8FOs>vt|jagW9pRFqwXY4lOJ*{+vk|6MGsZ< zoZAH%egp_z61$=nWukcynR;-~G33b8D!khT7QhCWM|2xS`K;`O8p#|zp?2g3%iIoB zT47Uq>@>iBmP9tF?0~L>Mpy&qOe-nSj0)JTweQiD49JcNEc;vsyob)u(4VXs53Bmc zbZ*M4EsF)be{p`|Xw4l6Z{SxixDk~3WY%;xgWV8ePcL;Qkr5edDP9e6rG^5tRL>4d zs&}CIoP$`fM|-n-{wcO4x%#I2V>)JJ$>pfELMq(COATQ3lY?-R9fyUkpdgt!=V8cx zTv!<3R))JUbgDMB_NworD`%}^_%7Y`iqeuv&g|s)#T9-uso?OvZG?q!j{@PVxb|CQ zay@r2ZQ=m>{U4l*!ABGcLcGb)bq!u=1A7l>sEarxRd{>Oe;oltB=zjf0kE}u20ait zach;}gaXCLhi(`t>hxrSZQubLjg&X3Q&sodT@#x;!t}p+q#9ZWS>)Z;(}nGK#L^jl z;-~%GfL`LVk9bvQGuR#>F9aahp2pkw58=_2wvDi)JD(C+{nqGv>ZvC%FnwjBY5Cyk zI(026Id2ySZ}PvWav`Cf4j$yyl`oh{@@~7HzcDLfO{;nfm1FQ+QBP&{1^D!I9$8iKr@)hZ zh}t?v#^2DsnDZE(mu3Rni4T|`q!3APD1> zq{0NeO-Ru=W2&2JqQE7ax`_(|A`&MOKwNraGA2w*(z2hLE;hZK4I0NV zE+_UaD$Ckvb#*TYZ1|v{$>l+4Jc$gS%0+3#IkA_qhgvK|9U@~#AWRI9w_D@y2m$fL zjJ66p7LFke2oSydTIqxTva?YT3CKTtGKE*h6_@VT2xHdY zIEbJRB(KnO{*SvJh4hQ_VsnCp7Cm=_vqYBNgnkiTzN5Y2P=>$X&*Im z$~JItD=5CEwS2lHZCD9S3-{Ru%Xx zqV*+5cN}{BHuKi zJ?lTA)ne1UZD&0a=&mJ*S6q@_Tf zzr9aE11>nDr1Z{kRsZs_zIPaol?o*`K!Gp9>fm2=WIYE`U3&8x!h!$EbT+>FfBD^p%9( zFN`OaniOuBOoJ@9BpvYEsrN5F|IvCq^<;!xCqWh!Ee3oEkpPl^cc+?P5z&!v!w4ob+ z@dSJ)kTtA-?qw6ct8$+f3OYa+69zHyk7WC8I$z7qic8gY)Z?;`fU?~%Y>IdBh>;n_ zvh(kY5pqu;iRocY>sVy>u$ntFUeOu`?@l*fV{B+0W*oe@!fFaMq%$!QtQ{r+yF{$*$k5V#8@{2< z(E_2Xg7>C<3Eqqhq0CeDn&RcD|7@W4X{B3YG^j#+jR%p|q9?A`>;4vDFq}~z%JQJ3 zH8{gwwQJU+B)U&Cd)rchdiqOxvnwPt-nS^}^5ld2?4q%c&4D5VMknO+3RM{C>D4rG zjsYQYtWLQ6i{FpzGhHgwwb6a@Bb3j(=3}cpp9LE^Kq$jg@f5Lt?5RYDDP|Im79R}B z`SH7NeoW{Il{^m1L55ZzR~!G%rh>Suc?^Wkt#v#*S?l6g3N4v^kSVUn+RtCASHJRt zL#WU8sAPS`uTlun|03%KQ%G<;3K5`QRNQfp;hZ$E6*nvD^NZMA#Uk|tqv57|E=Ihx z@nniEWr#&FJFwk$EiY=36VPqzD&n2e&KFP6DoUDoNmckbN=M)w#5u8o&bl^ztKqZ3 zLxt8~K2SlgM%V*TQyz6!e44F8(W)Ui#%ihiK22T3x~0V8b62;9a8hBf#9@W7+w0zU zElDC}1ue^|#nO*fF1pYq5^pSJ;7U}r4FK5sCt-vmF%xjP^`xXC^tmN@TiMK|I4T?Y zC6_B1F6Jc&IP0A?{y2|3R=@!PO4C#rl2``Y@&?t>O5<%|Pc}dNXnMJW?j7-~znXU5 zx-#F*46Tk#%&95x`-3$Po&`z~p3%6k)a2v=tDI^u5VRdY4YGeGCHz)?~h) z_>dczl6)+8y3V*OJN!*{vUIBArL<0h6NllXKYo>zu&;;8D?}D}wl%*=2+>0&PbwfZ z#V*d;J4?s`!)naJ)!b5a(TO8t1+FClaPX*>zOQ|%ud%Pc&;fuks|izRw#?0xHy2Qx z=1EUUfHI7BhYN!~t&OgUH6ud{@%#m-*gbT8DmYHDqZSaO;avM zP%u<33@=qg{E*u)Fav$zPhbYE>di51*LP6l@WZU8A+auhsl7u4XlbP3%rv_)$(lUKy#6ZsznYZ>bzxas`xqZwMbX4j1wOcr1?#!szJMwcaYbqr6JP1}!; z+$#KD`XYpjL_P`9&*=@~YNvZ{(&Su<(nfQ+bo99(IA+m#y;E1*mjI;o+UXX;ljmch zf^B+hjNjeu>tG-XI$g6r5H*pS?os}t>aca?76PG2b?9MP;DsweA~* z>tfr)8Ka_XU+_tI`Q#U3^rEd|HT@~KkokTU8!3nxNOjFVq~-cJ-YWhYL?Q=F<_6F- zNHs|tI{16@CI2o}^Jwi8xb(cdOZoE31Tn;t?tU*{0B26Gg@&+pKVB$}E1rxX3cVRW zrn2jP(>Dc?qnfVq&qkmPn!pg+xj|q2RvXP||NF-n$pXn9%BOmDG6>F-uYC(U#M+w@+Sa|DB)GoIoVF`%31P zJgl?4w%+S1V*lgkXDW_u`?5F40nk+C^A6~cbUuGTV)f~bvrSzZ9aKEM4R=4d#}ET4 zZQ&Z9ROF}D$}U#iAYI}zT+pWmtrH9ZQdOkqJve2u_zLnDU|~Nu6OkC8riYuK&xaOh z+)~*G;9*HvLO)$VRs{2|T((&#Ni=b~gOANqX-ALwTz<-DYJ!wc;A$0jSS{$(`)<6^ zQrAp=QbOjMtLfD}?w$8tHWQxznqx^P`W8?YXUu-7km8;F@JpSi^ zLXW%?vbfRwq2hRyyMPX}ENsk!vA=?~QTHFtnEv3p=S$AeK7qw?@Z*9d11L6hJ+j1C zY;pSUoG))mKj>C&LhQ4Hwg~Mr3Mf>o*c-*^(BR_hze5=4A`U(x!hn;jh(FHF^X;_g zU9-ilQtw7RNlu}`qzX;{afhqAC&{TDg(kq|OHl^ujx&3$Tb+ias#46RlX6)TZS|Z?*HflGZZX3Ac-AznBMB?*)H#@Jv7FI6;07pVDb9;HI{_0E9ZWoIU+6xtRjM8 zKraAcfLueCm(g}iE`&&Cru{zL$>d?UUlZgcmtMwMHy$mjV_ZuJmUnax!|lv^QbdZ8 zCnF$+e~e2fqTD188NO=%?Vwkvh@~7BD2!Q8S;O2HeN&&4i+_V6z&7_AK zLp`H^`|kU3-o;=$*&v*d*4s0SyA{hBv|6fHkDrqZ>wYP8(`TP`e zn0~s2q}Uv8#uVGG{B>eYuj@XwE8sS#7bScxD5f>cwQCGs4ly)h$4+{d);L>#BR!bO z;QKr>VF-MQ6^e>54+Gd5lK6Ko)KNMqq;P8Rp@!o2L5=?PQeb_?sCZ_4$?i`w-mjDC z39U({j1@#wV8>{Y6_h=32>-Gzwbu+GTy^S_BL8yR!e+rX- z-*@ldnT&t>_oS#b{{Y=0+~gRY*hkp(*O*|^KC6;Wgz$^&WmL-6?)!>`&%rLS$I6Jb z75Ukq7e)-h;84iT0gQT7kiG$`fQpl{1C?eTTuU(NF@B-bBX%8O#(LL5xkk44P|F%( z%mH6nA_T)kuMoH)gKq9&eZA|CS z=9YWpzv9G>JI%pq0o&eJT9}XiN*_RWuVtEG=rxEWc=|Ge79nC*C#g)moSCce?n>(_2E)2v)bwHOEG!-cl0yMr~dv>HI;Oy9~W(=4}QMPj%B3ZpHCb& z>P7=_3q;rL_s9HcMq14K0>*&o+p6qxMtU)9b}7adb1u6J$p*8w{q0Oz5U;bDvTL05 z7}GtJrS|5ky=}g!c8h0@w!Dd991{TGm#mu8-0>_sz`|aA)15yU^=joN$0a&~0(5=AOy@Prs(a3u8IaBWzvXBEpH2 z3>ID0R1jC#>ac+*1+FPx5sW*v$)z`zJwb&ZcTzW>aQr@r4=is2C9ZhaXrx3Wwvg!x z2%blYt`T`(1p&OpdQbcvtRA2WFh)?cZl4X1DeJ4!(O^ImI*U+GK8CZ{JOy}TbUeTs z6RaZ6vd&DbEt<-9a+nl!VdROfo$Q$9JQR8yeR>K`Xk}G{SAmn_A0X(1~|@obUEGkuvg;NnVCaUXn9(@*NzGX8|y5y6Rx0R$5ms(hR%wuja!P z!=d8Pg3s#TMv0>g zSZ%RqA=!6>=yUdSQv8R90@AfY0BpMuxOMLfL>JnH_f+os&aw{*2+P9EjnPZ0$OEK; z;#>34sb&fR#yWQ#i1Wv_xvHoaT5t}GU04H8_vqBiYa7m|Wa0#$LtFU0AB9fyhc>Ju zLQeL}Lo~#Q5iDMDZ5ZH%4O!%iRm4!u0Ey(MIRYNIxNwe7G=ngJ(4DdzMum*e&YiDL z&#S?M1(EO(TPF^^Y&u+77m83Jf)m^d&lPLtYS>ZPHi&y*t=?`p=%%-HjyF!!QEj=?vksy*f*j$sXR4u0 z{8En%Ds`ki?S>4m>S{?IL9ln;&U!t~VzYxy|HohvPn5Xq&A~aT|D>~+bfzSykyY&{ z&%q$qRXFS4-XOOE?wbH@du@)dv<9Fy%1aJd4I~|yA5Jm0klB=zn?a&N3_& zv*e>#oN!$ld85_7TpGi#mnQU6#Y=KZfJ`4+-Z%DQ{w$!KtIpS~-5V*fgoDtaUj=~s zHAr6wcRm#^Sb`IHK(mD3h`?3CTYBTyEz8Ho{6oBgqJY>Z1{UpST4RLRq$xi*tx%vm zhs^QFgj)Zc2^^_uwsEUaMK`Mm7P!0*sp#4Fp>J5~I z20AgBBO+{UHtlH-_Kp8e4qQ&N5jPhn{gra`{P+nnyK%n>jxpqhNC5w0c#cQE1a$m< z8@cP-%nSeU%ZM(v=YLM~F#OeT| z#$I6A_H+T$xp%7P=FvDQmk`)`{M$*g?>@sNk0k}zQ!KvJ_fk7rmB%-AHpm;VuZzn< zx6pxpz?}>FwDtvDlIz51h#!^wrbA}Tl&pC6h8FAMpB7ABak^jgEI^w#mc3ivw#b7j z$`ubp2$)QKo0!5AcotT#b-!O0r_|ImQYa<;k4VP9`tUf^5}0}T@YLaf$*qPtfI{TZ#85QpFq;o$MV=@ClK{)!w-z?FheM868 z_$f{p@3o-tbNHZ$fe52?zn?PO9+xX+t(rX<7 za_=b;#@&2QM-j#=Uzr~MoLX(BFKG<>2r`&)uuwFJ2;v>Yr-{!_S|WOMxm^UfH4k~C zkr*H%kRL;*EwY65PfUx)U9!Im5K3ElMF-1}r=^V0D_#jM^{Xt*!a|6xx%fV#P)!78 z9BJxUiuoRNGiT@Ezm>?3AHEkpsg|UbCXE?9V&ng-RP)Rx#pmX{D+I(I;`_t<#|;8xk!N(ZdSpK{>+-Vz0rbo zKJSs7aj>Va*IKYx?;E(*a0>Zk>0aIqI~t6-{=89da0epSc}vi+-TP`bGJDek1ioqe zNlckSyd@vK*paE6=P48f|S@q zdymf6&VK2jR~0!laujM=bbYi4siI9XVfx`?sM7Tg3URF{csFK3BhaoHh|){si80pJSo>fj&jkzjWVm{I`IC zbzIJb28Tv6G=Au!d|BsM=O&k?aFHY0euQh6e(m`hSOqIQIjy!tKc1&(43oNPz` z%*snI+S3Z~oDzG3;1fhbdYnJQVQ!ggYOfba#nfBrM`I)KK7)R+wMS}KdOhg-W|b?> znuFY3!7xkY?EzfJVvG0261lH7XM0Wn`FTGn{b&#EvK^k6%b7MWaC4EdK8TSRP#v% zy@7_SSOC)-fWy!HCR8B2RSEJK%&}L;CUbCUYTAcg@My9TT?{z|&xg9x_i<8NTZ{2y z%o;2f?D;9@nUwtn%U1>dS4$(+vDq=cx87qCXAYnPE()-DjwqQ_zKiVww(p~~EO{IM zQwTVx{!?tK$k^A?rTiqP6-~o-SkgT(+YTSd*Y%&NFH#$hdAHs?Bm%T|wY9)Y3UCYi zda8y6n3D%d_7B`(su_@NV9``bwZG#CUquUO)dl;VFGswa!eR!w{6O>h`Kj15Rn}^H z-Jj)JyFGM7@sxf`1nOxb=XR{sN2+-+u+_kOHR!Ic8j1fl2Z8^dEpAS}sD5!*RIp>AnMIC57|C#y9A$EzGhU-qOLw3~|#b5qO2iJk_Q4Z8xh6!sY@GnTW~&Q9!Q0 zT&r}iEmxqL5Jcx?Y1@GzFd1)if?4jWU8CI*oJ!lnP#1c+WvUxAI1M2&;;dI1osNh% z=y<=*u=GCia*|zU{A65djRS*@gmT$PC_9k<>+ci1EH*P4JgBU^w zRGzC1d@Kyq!hp{90_S}I%}9V24uP_Z+3%fxo_syxKydWF|9ZA#6^l$ajGer(&Z#0? zdU69qbT23I3*h6xn%y7f(psvW`g*rE>@x@MrwTbr9IvEGq9euU|}!{yvF_UbWYpwi4|pX9VbY(^CEP2K{`E%bF_=vOTzx@( zvxt)>70gHatu$d6=%2f`v(m8Zq_bbIGOF+}q0L4F7h-i9!-JBgSR-4KOR0=A|yCh(yqh)1M=;bA+D8q*T~tQxX8jb z2*#)!e}mhE8?0-9HLVMUXw_&gSV6qtKDCx2Ll~jsxncP(jbeE2ZT(vJJx3)VEWE2G z8i+CNT`t?MN3&+}+GgY+!yKsK)h;v^9KJppT;yK5Sd3uA6Jw| z>zC{lKfwb|^u4 zOU|z9lw9cz38ezYPlvbVJ4_Ay;cV`@m_DX7JtVFc$K zB%#Y@zEE3<{H0l$7AgnWuryoE&{H>=-fy5EO}u5J$qbG>(Eqd z9_S!iH2AGxH=|NgPP$PQrzLKJkiW}u64rWPzp@)xW(mkC{56!=te2T)8YSVO5kRl1 zIDzGm^P^UAtoQL0-+OLN@VDG0_V(zAJ8z(7YB6(7!av%H1lq**eL>umIAGS$Kop5? zxiHsvfVlDJN!p!s}}1J%`-16yix~Rws1hONYC36 z=sGrsa&S7VjYtJpA&#M&9uDO*htH)J{nfgU11Mo&arU%HrAPW1GZ@&CI&J?kMH>^j zBe;*s_2nTasD=^h$%R13E0yXWSOBu`?u9Ha2qbJ9Voqbu$6P8frStv0e4KTOqm2Wa zTv(oLCN7!ofF#n(q+kD%>?ziPl#O+OtiIOtg}szb(*bz%T_%beEj&h0s%=T{kBZUb zrv-Kw30`etZ+r?<+y54LNY_a1jck+62{#7gWjCmReDxYRJX&}cUCTK?^Xdj43%?)f zzh`$BY?ZF1gfBC*2DrWObk?SNlGGsGy`7vN2^a||04J5gED&$ILdXJ_l$K#EEzNB- zP|eU*-L6PkeKWDrs%-ID8n+#-bKPi=qYRH;|J&quLf}zyPmzk|`N@d#h!cf=;yJ%B zE9Kn%)NOCAbIt+@jE#BZ$aOXY9d$)^duYfxrq$>sM`u@k(`{T{*Uor9wtyIP#CQxTrDnQ?6JzQ6$M}0cxAU{jp&9)cSgKGzb>-3ghZ7Q_S?;_>pVXCwamfx0C@@d= zZ14zwAn(A}Bm9wQTb4-Rho8v9LOU2zUaDBw8LKD;`l6HOL|M&(R! z^bE*kaR$U=6sFKB&;&O-Z|P@4#01;DL=hRr(Gl_WbV{>)!lTNWV{Jg^f=zSEKtLD+ zaJWHZb+L*_4@!2*8I4dCx8MDC6Cok5{_jGUrJGp&^YLVCl^@kWZ^{Zv1PN#aLI}-MC@PRP!VaG+Tnz z*H!2~H=u!#{4|4YJjLjF2=gtN-By&#S{aZw8-B9-g-o8{f%qKkMl%b*B!9oZH&g6? zg{c?ccS!+K57W1RZbk<*4eS@-Rmz|4q9d|U;A2lpeRpI&N-i7^Uk?M= zm6l(+O6>PG+MyxBz1Y%ciZ(#5>briD<|Raj8B2h!23{AkCabX!6bO-1DzV3ciM(G$ zBN8T=J-}a;3&>g&71h{Ao@uwloo^ByySF)ARL~n|qVjc11wJqhd>eKjBsv_OqXEqj z?k*eM<4YS~-Ks8OB5~m_s%(9-rs#`GBpNGWp5U$PB1yyEOEi1thyx*67@Vvog6uEh2-3=7VzX`n$8|Z z#-d(54#y5|va_>&Nm0=vL8KqumxYK~$6_LeLlK`}zw3zUMg*MY9}OXTqm*2-Iq;Mtq?Wz}$)Y_WJ{) z|0=eE-g(vI?2>yS9{wYU$%SBirXIRAtr6Y~W#q)AuGb}$@J$ZU&sZ7Ky)L3cz$IuJ zG?=$%BrDEV%romx^F+Inz>;n7awjf7!#py$Zl1qrT0}Zf8akig6_41=0BeqFrWlwr z7>AAx0e@`EU=}R(P$xm4Hijq}J*BL~vn`)S`X0Gje51u~A%4ik=+_(HSi7mr~FIBYXFkaLHEvNo`Fr4TPi*>^SqbVB~8=N#qG55^ZWinh;7M^ zV8uo8Jb5%3r9G$>TTWVB4d02tl{U03^$mqsP^E2vA$GIeTSB3QGzaogAhDa`UcW1o zCTe;)m-=5~=5-1^G=7Ua`nEK#4+i;d_Ze;i6Ic1yz6o>Ip}JeXg6C zQuNbyLxiytsi>a{wxd4V7@q$Zmcrr_GhEdimoI>FdT!&R7hu;gr%F=rtsOHOxq0vL z2z`Rr)GrTHQW%~S10Byie3~72GZ&n;+Oa|D$~+G?+^S%C;fb<953VVKNUsZ)cj1iO zGl4?DDvZA7WToFck#U;0m^6s?FQ$(=%+f-u32 zrUe~oDhDz0Oj{@*n(XvhQrdiSLr17f4x!~Kh=jGFM9u7U;oZAyL*s#dgC&x7QKI4+ z-D@(AGx>?~a9Fa9lw^b|WNBy+&9q$kS4}^DR8dKD*0V0Tf$Eo$rE!1(g}U-=y4Skq z3V}iMa%r^9wK*NfHN@|z-#NuT#7nE$<_}SyaqfK(3{J6l1NcV(Ice#GK7frz!m3Bd zA8B}JAvUrJ@R)l-WZBa^C2eutoGILgTL+CuLYN`>uNF3UfKfHHd@{#)3NdW%b2DfZ zlcjb?L|3&sin7*baFXvpRo!3n*qVC%XdiD^cmsar<{Rqa9J{?kLYM(-0p$wA4u|tU z6ZC~N8lr|gA1mhy14LN6iTHHWVDBF|U@S1b{5zH_3@(gU7Dx2${(dkn^p(@dS30NXDp#WYSd9lgrnUtWnoAO?pbeGcl+d_<( z0LK4@rV{**4v2xkMZ?RS=Z>}A8+iAwp@GH964AH#Lxl_@gAxW6VzDIF8+42tp7h5de^dJ>J3g=V=7VqIsCW6e#i99bE>#ux@gb;lH}opIpYTTusOi8?5- zNVRCDfLy=JSI@&Y>EzV9vtUyu6Okx-RP|Zx=_#hXjP&I4uM~6(F^;)EYk`%Wd!a_KgdW*b3?ARf*j0=zHAYcA)_1`xZw!>B7 zYr=P19X+(&4Q*xb&)U_HS`&x}ol{HUv9npX8Q{$LE66x@S6yvbw&KjZY{g3WbpjRp z70Bg1Bt&i-yaiL1zk9F>t>xj}m$2lTy`ko2F$sQnz~Up&+Ep0B^AhZWt1oT|={?<7 z))>$pIbgb zc1h}Mlj!W|n#mojVJe2^c>QwB4_Z*62r*;STJ<9vkx;ha654qun~T>l_6Rca`a%!__GM399e1I^!D8k6w31xr$NgpDXunH0VHqh;hepho;0+ z5CqlCw!X!F4nZ(P10Bkrn7Fv z^`vF+Wge*pd z(%sXrj8>=_2cRBKfPxBAt9+2}YG@&ASANB5({3)NqQOl=8hC}J!f|C^mgZOV?2X6s z(gLd?amwP^h3Hp6xS9%FvVGed|EFhr`i0#~bo+kyqM|eJafg*anjlgXiW8u?x|1dF zlnBHUl=8o74|O(X^hm-!t8D`7fH?5CJt%?5vl|Us0y!x`{Q&a4A}vwuT)G{{dOaiLmgdOaCP7-U)pmp%W_2iK))62~d5s{|t@sq1};XOXs8 zXeNiwi@KMz_7i;bPYPAoi*wQ`{3hAf7HZ3OPPyw z^R4Fljof5s$*OcTA=Cn4P$*C3tzZw}cH5!LZ!P>|ks82J)F$HbnAxB@!K=`3s%SR3 zS-Lh0({1uFhdnXu@P{Q?zsk=o(dc?}wj$CifLoM})C32B#yF#B_RuVO`@I(Bid4Wn zXWZd+?|(fweM}Gb-$z@j@M!&_Cr^U zRhu|z1f|;wWUeYHpXU9moFkA7aXJY}ga8Pi9|rSi1x+%@#UL_8J3219jv-6$%WC~y z>NtsFCx>vc9mQmodMB^g*iIfhx?E{T^Qx`Qv1R$M&-bLmk`Vt5$&1uIV{;=p>gviT z6BlppWVSMllhDB1iF{?NY&zKz?8=VXiz6b!}K z+TEr7JOC3)mts6L_9rO*IWc(7W{h`3!iuYp$tqR+F}8EA3}rS2+X@jSECZJD1gq9# z>rJ{4Pq?tBQ3dDPnB81LbmrSE6!D}H29CP0MIZ}tY zj6QfGpE>YtT2uxK#_epH4M8T2HH5k};$&NeFFE7WmA2$;kra?!@#XA{tGgy5C14|Z z^h8q2^30;X@Og|1ZyUlI0)uo}W5cDXznq(a>%SRB3W=JujxF$sQdz!gpQqRJsLV|A zV4ZtvaA<_Tq_y-p4`^e=|L}H~H=THH51OEN&XR+P*6*&8J&34-;f`vqCgQOlG6He z?XQFuW=HuR;}T>oZX&q-LNHidgWE>EFlg$CnUPN_8AEbf)v z!Z{Ig!ml6dBG=kQ=X0P^axfO|;nw_k2C2h!5LbHP%``1bv0i~}g>#I-Em~di`S3P) z%j4ZxTjONetn>z@2chpYrVPm%qNX{d_v@fj2CY?6znty27>J*iJ2vgo*?2sr5PTci zH_nVsc`nCKQV?z50BC)(LC#q#HrMJRSL0Bn#Gf&X(@3Ja<0l3GtKuy_8>5!ZzE8P- zEPZBp8iIjVe~FZp+xTyp1Mvu;Vv!|4JO$ht$2TyDtYoOq;;X6QC87%~W*ra&W*U|b zjh5j+Zd{7+4eKoNdfsx?FMhu4nOp?(iq2;B1NFc{RH>?chwT8O4)d;W?#s}?u3Lv% z1L8rrK?V>yR<)j&Fowlfy>1}OTj~I0UkL_CP=&DN%Id}K_x^-Ox`v~!I&4>d7oAlL zrGA?2>DFl_Sj7-9O%(4dvgWT3XJaBwVV}<@g_5Vm1Bos7$1fI0h{44~Dp!!OgEa2eUm?>+b)n)*xSJP!`$zxPCa9-906DBa#Jn%)mx>5u#PVJ;9NW?5dT1)Ejw zt--K}Eyo+#l7_B*`@Q^4(IKQ1kXWvv`i-^yz--iBSk`3;ReYX5i4+iL6+Xrxu zb(+`+>=W5)(1!YDNIC_tS?nex>$JaRzz@^60z~c6vf_MO?J{eDi|#WR0?qtPebY4a zC2>KqOEBU%n+vkLJhCB`89`07rPyO`)F};!YMDtp2PCtn|uN>m(kC{sE?N~}(fbCE)G>ylA4Z!>hIz+_uhMZXPw(jgbyxyNxHP95oY9ET}g8We0Xw=!155GWUR( zk?*}n3h{N>HWk;hwAgwP17l_IOzoso-flh z2#fjkr1E8pyY_?I{2|n8c2~${lCZ&Sbdhz{Yuiwv;j`TM?AdQ#KbF#Q2uj#=;S)y`hR-BwZVa&VLenRRA#7y|}NUbzbDCZQuM%7lpZ0UjiCSW5m>z)7uq z2VE4Bo1I9?0z9$B`8rRSF#|4%j3Zy~6R-v;W7Ugs_rlUJf~O7RjIoo3AwJp8AJ9IP`7(^OW6kXi=`$Bl%4dleZD<=eQo7}st5=7f{to1Bb#qc>6GY0|7hA={7RWKCDF5~6wTTZB+zCw{8~=1AgFtM>E2Lz81D#y@)Dd#Ut7Emz1Ccf@zI6w$ZZp4PNX zO~oDkch?9pz^m|^4=rn3q^e+0hw!vH+k9iY%5&mOuSJDCz~EXDO82}DbaCJm?qW`# zBe7i5Ra-6FktN8XE8^%4(^n!QnADQe8X;wSHCCWSdcORV*x2)5tacbx(_=$54CQ8! zG`!>c5aewO8X3kiKqsQm`yQ>DDdSvj>yp!BL6m-@3<&v`My}6=oTm0N8yO&aGRfDV ze9<B)e7GQ($Oc!6>m<>F}!sP zhva-p2#`f6a6;@Zz|y@A>1tBwP=6xP9u@lp&$dlBGAAW_M{)lrWKwB72f=++?W`)f z4sQr**Yd-{f>P7U&v>GcbBY4FhdVk}bAi@SHI&7={BW6qq%Y~@O2n1jVF3F;bmd5c zkuviL4Bqb*h4wV443x)<#?{ruwGMcvnEFjSE9{?I8cK4?s%j*C(=Y~Y8kT^udh5nR-+*QX+q*Uh(wQv1wlv8&>a49(0e z<-Ti>?UqJ)VR5S%;b*>k;(E@!*F=haN|;VSdDRgHDp4T@MtXvJJLiFecJ1-!I=Wd$ z;g$mPOB`0pb{4<-`R1&HjTSG?g33kZs&HzIC^1!_73tk@Vg0q$J+$aPr-}g9KXB~t z7nO{QtOn4D&A!@WS&2k{UhxowzBco0rWP)WivwN%_x?%uq|9| z0^FUSZpO|IVONQ;?;^e1Paz=yL&*NkR30UGMkQjY0w!5`BSKFoz>^yqOB2>J)H^A3 zcclM8DrVVvv;f_0k1&}BRg0PsC+`FOP*?mWG1}K^P7c1#{jr&#-umCOu(nB{H5v*6 z58WdQW7|=F(j0j$8eu{x!u+c=(3RN3)Nmc3?n0%>gKpowfUDnplzKzsU1H{~w}-1} zR@O7q4B9Of=9agB8m}0qM3wUGaheXeM#vkzF6xfYbe!-@ZNNd|JseTn;{b206i0uv zb1ID-(ygdtgvw}S%l#Ar%BCGeI(%lF<>-e{If;eo5z8kuaOuPwp?jxo*B3oG4Ici8 zOt^b2;Uu=6*_IwqrmALT{Xl9b0c80XcBzvRJa|yV?D?4W11-UMogrF4{djs5AcG zW;g_ZLO#;4X}2Rnc{w4y00zveVVP+osXcWZ&yx(2@gb-D#U8D9i-OimQ$r!s8YIr8 zrYmuWE1do^#6&5+ZmR-UDFGW9@NDVGYUwrVSWoBb0RjhOh=(+N5Ae(h_ zUif5TX<^pHjjNF$F_ru@SYv891~<(oVL1XV7It)O*GR=VAKzM8(9I6IW(f4aAKyt5K%BV( zL8gUiTrl;nP8^^w)n5`SXqK7ZviFA1$(J5%$A+>&*A$%2zr;0aqbAu9fd%6&E2<#V zXm|?ROEVZ>mt}0UKwy2#zuK)JZUAFe?Lx`d97jZ=0xg_mBm|u9)f$=92gFny z5oj$rK!@EAa?8sXnF~q=Ozlle2`RCt)@v=`>;~?43eBpIv25a zp0^oxSy)nxGXM+`rU|d67E)Ai<{XXlaS@*~KZrXu8UO5zh88ZMIc4>2Ca9D|NlFPt z!BWH5SUMCpjzZ$~$JB&|OaLS4ggldjR`sy=(|3GjT;pfH%AzkM05kxt6wq8HNC}S< z8pJc|0yD=SkW))s3O^e^mIpT7GtnV|f;%o-!4t0za=Hj?_S0H6d`Fe8+`ZF1@UDbA zVeEwitsfGHeNI!&-y%i6Uhl#78Ow3U$;XmeAKZ0L0w)~uyi2B4uf$(E<$2pOuG2B1 z+pPt+X_;n_cdx}6#o1MAw~skb5vT%#ynEt+Ck+b>wNlR1Kq7ho?^DeHIf@t66sKlP zg&*;Bd<~XrO*tr<;`UNoL35%?NaLdMCn;xV+D;h-Penp+BHMM5vZlE~Ho%}P&TM)( zak4HuT3ym_wG?Qf$F)WF}M~e;YlfcBvnAJmgeWSI5ityp9%|`iH0kvR$ z67}9@3EDJ#lsu~A|DO~8^eP|572JlIt8C09bZaG+0f=rW^ja}fXsE<4~emX#=G}ceZ%rjhpSa8K|OQEvVM?3 z36O0YGR}eOvQ^&DC=|`Wg6~Wa4ZfrOc+v;KZq=V>p_a z1lX^M9#NHh<_9~Zhj-qb_|6y=`L7BwfuRB|ECT>(A81dOOLph2@Q*>uz3wNsiH;_D zA~8V#xrL^WJ-2p(fZG8M3wo=(bllV{iB3D>rs9$ANBHl$3l|^!H`?%*w%iaDgI7BB zZ5_)M4-$2ZSxsKbT?2F$4JPsSKQn)x*>5Ai6qHC%zp z(>c=jiq6R3ocE)vAPb`R>p()&EIal`ltzjnQ13+rdV%lQv9DjROfs~s+k2MF$-?2- zs^cJ5Lm={7qLlG~?YsS7bFVH9ZM?_sMV#_FKJmrlxEk2p^~&Ms4T*r@yV7zyjo)2V zm~&S>sL4CEowp9}a~WBc4ToCzG4`mjMi1Hx^fcka{}H3dU-j7Yi=g|XCKhaJ52Pk>tVI#WHe`Wf4k->E6eFJd2biAU>&A_SP&-8>l6-rm%9%YUC}9fa<`qZJKy2Tk z(U$KM3*j(@EHe1tF7-?{%XrZw7SjSa z>_>=zlP~PJqO~T;7SmFqZqybKJOZ$+|&$ToHdUrGJlh0s+LB zwl_3uy}pD$8WwMzsn9Vc0{K*#cz%f-k7{A3ljAUi4)ctba04>kfY;&rr@TOon^0xx zsOD+TKrqNmaA$MewN|v{$(0Z>9=6QE#dFNfG*D%1fC)APCrg+;`npq_UH&{Ve+zR^ zJiuhTrtmlqrrGv-II4Dzh5*uKcmI^6Upg^fqLK5gcfR6VZqE}p_txZxb>xd7b5^D5 zEb*?oX2>@!U!%yIOsLGTg|{gu?yXj^=l8I)=z_LIl(MHAqq`*)-#Uu0!m!N%z&dFo zXx|$^Ys?ohL#sJ#Bj~3C9sid?ZgH+|!)d1?$JBOtpGg9?VRyl0&*oiIxc5a<<0^~W zRP-&z+&lykWy7alJRbsQX!I6ghIEf86BBJ?3r+q$=Rl~Tr3?$0$;7aSw>MRgbi2^U z__V;TCF=Ap25+X3L8E6h5CkR9xny%lHAc}+p9v&@HxQQ<8f zA9fow{j?`uDYrZnRorZrWw=M{@wya5{RRtG_q1#2Qz!n#6mN=nl7c5rFQ@LB`VB%h zYGEg5n%~gImY2>3wbC-(hP^A&fwSVKsUcq$BMVV;a0`dyV$yj zOiGjUXNOWbguK(29*kryEF`?cM!4pEGv8Bv!7wHY;zKg3$-YpIKsPy`$n-G>$>0a| z%g3%ksH4J63Rv$)r^p?65L57ZE4eM?DCvysQsxDkZN^#EkJJ9WUg`2OhIjk+(P!oK zjY08ZNL4zcTq#>;c(?zhj$^%kXd6(K0tcP%r81vAqls0;>dD%&%3=fY`GXiuRZ_A3 zjmIa7H{)mHLY!iQ+rvlAb8m#IjwSy(%|AvM0&q3G@g2X6xCQra&1lgswnQ|H-p;!3 zYK}32;;$j5d&G+3S6vzY^CSy4^azs){N9A0b{db#-=kRzAg@>fvg~eHu)Hoe{3KZ_dH91?lJ)6B^3w4z?L~meU zQS}%fpvMHqp>?XAaIk0&l_lD(gQC6Zaq&~sEe+iB`1wNq$JsyBIa_@Xx|y|~sPoIJ z^fdFmF>(jZ?v(y08+6&5a6?lhu5gT=w+p&lCtDUAOL(C^5dAPwIcL08?DZAG&{Sg9H zvs4*<&O?qge|468y^)6l0w5ymzNA36VKXI1>V08g*!@|N)>S~0li0r!CD|9OHeD;~ zJ7!b>$S}|S2=wjr9iq4XT;b%2b~#;t2N=+5wP&WgR~kC~e=D?i42kKj0-;)0v4T-J zz#g!Cp^R)*ZKo2+gRiY5O0xzGi4>iUkjNYEf&<1uXIhZ>0O6z(G|w9B2%IT1Dw$%U^6UeX2FAXJ>>}wzl~wq=zstx5bDx3 z#afHUC2`V$UTjI=g{=TZ3w|HJ>-u}|H6twXVymr?<&|W&zPYlU>a8s}v+YS=PvHbGjgHiX7N^JKCJrG- zy6Ln3ZZwk<#6u^2GtP{7xowGb05q5n-**Ah$pyZYO%e*FWy$&d>t~m#kKA%1qv=Gz zV|(pPIk7kQJK@@UYB3|hx~-%gxDL%?3{x>)Ah3g{!qMQeKRDsr^Jp8i_R{zW=UJFe z38A=TDK#)frSmdIKQj{GGY#TYj%wGlgjIjXRq0-lwGf4+KPPg1C{jO>ICXE0s6OPV zZ)Fuo(w=U_A+ID)xCN^5zF?+Zk=8mP+T(WNdD~t1Q88=Ft2<)DvrGQh2ANvEXPE^{ zM*(pj(<;(6TA|Zf6b&XUcl}{2^%gBIlG4mL)itXCll{1a1GKH}k4WjN?#2U7u{#lHm7TK^ z74wF%-n>jKpdZ$Lz>Y0za~lWz0xS@2iSJuk5&yqy#>Y< z5Zn^1%X_)R@34TiH}8CbaBb^M!-T{aCj$~YRxoo2AoBMUY=OA9$=}MZXGxX;x`cqq=YB*J=e1}08lCw|1CEpb3^LAmqI^^*Gd|*0uJum zTjb%@_HlT9s%vW1mMa*OE3TX)#)vqO_<8mDz@`!Xqw>T-4z++11X;phsGKs%Xq4fd zS88Ij^Wv%6OvMtMUcy_LAl;d(j$5oRPnQQ?Acw_+Z~weE*3~>a9Kta6F28zVvBc@; zlu~9Jton^W$Qy!wm|h>ESg|W(ML^)y34gRbdM@XRSYs~pm4U?GIJwheMeudz8{mTA zoWbFrLvXCzmY*JpmX!w=WsbTFWF!Q$?r&+{?7=~Gq#`#hqN}F9F()W$bKj)#NZ>>JJQ zeYBB@_g&A;{U$_P6k|6O$^F~A?@!H7Y=C%&(94p0kQmVbzb1S`wK?DbyHy1P(%oA1 z5a4&zs1hpU9fvv_L~xo+n(BNVuV4f(zVGN=V_KL^-{iaCHMz{o2J_^8RvoToQ9d{m zJC+<*#F-GI*V2Sib3DG)WwPTzQJmW2LU5`!W7Pn_bxi_IgA>t+%iYfD@mwkQ)7eS3 z7felHa1n^(12p*qwve0k9u<}24X1`kEC-~-mK=6IhilJj#aB4wYd7&b{(TEZW>=TW z>vx#>2Bw5So~33OeC7wh>vbpoAo0hl{r3`2L^Sr5);rkPUrjAUdK}B)f1p)Q@$9VJ z)@daVu)ByAk^t;~&|U9*I1#^9^X8qG)Dl*aPSIld^&W8+t zK8=~ye$ntdD2PDDhGqB0R)f4Nd}gtxzpU5?>ivE8 z`XodI<&~P9#1W3hrN6RkDkm)qx6mIkWe&Z&C^F$T9dQ* zfrk||ZQ`HD~x4*(&(*R=qDj@z#^c4V7r@qdR9o;mwx2qiY?^Z2( ztQjcHYDmLYUS}Q)$TVrmexgxWFk-z)RT*%5`N76pjf0rKt>aY;UJtvp->Kj!7op>S zClLNfQr_=Os;O8?TGJeD8O1_-`&!v2IZ|HlVjJ$%>>hn4#y08z63^j^NrD;}eUh=R z0VC;er-6kOSpFX0mw;w|LBjBF7~=mttHB2B-L_FB5b;Y$oQ*;O;O1)(hwb9Q-z=Yh z4;ofw<{gS`I2RnRl3`YENQdYix>qG*tFjc`dHLSbEi-H0GM`ex>b;M3O+QHRY z24s<&koW-U-x~WUG!^DQXQR(uZnZi1L$utP!@{d?JeXfx?u=|;QR00EQX^40<_8>8@QGWo?4g|DgHFaZMtJb!Cap}K?U2JH_UAS zxF?nN_X4{l(%Y0faD2E0I(yKG6}#w7sz(}I01cmI;mLsk4#v5p4H7NG?7E%*KvaoT zFrQ?Xt2H-WR^;EmqMDcuWVrr0S-KkRjO)Y4+av?HZGI`UgS-pi!IJ7xj_(nnCDdGI zq?$0%H)Jg5BQ9$9XCFgc<+N@Mv4b0K(zwbN(D;Nrq}#d{WCxPYjPn`__;sFt9!C>_ zfdU?_(~$!2;~u$almMTX!*z7fjf*FBghldg4F~Cy%=JMbnc7qmx@o`H7EeGGqD^TC9}G5Yt8?V(VagL6p^3<|HxJrqV;B{xni)u z_k`k9H7{$rN+=1Nx9}|D04qY4zvJ`w5YehP<3kH$Pvf-8f?AjzM!o1Q`S`d zrp8B_5Vo}#LyhhE{NaP|nlMq&;{KG}3p=$@Y}!z!RhxH7sAqwtxs`!Aa%I!r_)^o9 zg24>N8r_-I2vQT!C~W6-Jva?9WK?dNHjmD~piLL^ubR0tBtJC~>}nq(;5)>z*G??s6k@r}BMNJ!QBpn@lO zEBt^=7(&7v?ERbLe}Pma&Ury9f!K+uS`r3iiF3BA^4}^dc&B_nf;BN^sS^QX4oxbl zj1H*$473G2gm*hBWmcI9c*+jID#vPtgO7=AW&$Ob5bmkhR6`K*mNw-Ta&5PFd}SjS zbWCX4!sIOu>X)jFWhmdX^L7)=ZYxvvdLFTS+L<)xmzN0GDB|@3fbjXNng3 z-JlwPVd`g-J+#^zcQ6MpY z_kd)y_RT6_`t1tdkV-jTNFUbSX>%E|Cjbl3% zjyM(!?Ww}>Pa-rMRX0t|zB1803aMuqL#{rV9DU!Q7a?>O!3RwwfNJQB>-X?XV;7d< zqXB?x&vi%_O#8MIbXRR2K$I4kE+y_QrjH=Tr$|}m`Cc%Py z`FH)Hw$+4-HbnohSpLQuv7F~5doo-z!Hm#)Gl9desO{A`7)IRD9$)HpU%*8|c{XdY z5pU$=Cg6JDGtjMG#Dt(KJ$o@8&o3F}nNH^g$L9>1P_{8kn=E#6e9zg|$_YhIJPX!r zGyKB?$F1CZxA^veF=K;a%VVp5I@X)6C%2uox}kfqo5bRNt} zx4*Uj)NPM*aJvIDH+jEPl*0$fht%4Q^~ zfuppfyue==^Q-`WRqa{%?RNNJq2_m^Zvh=6Uu-8MS6eGGs$qpzO}Cx}(?D#^%g+Z3 z+FeKlG$~pic-=ZZo{7zD4&#sgR>u+n@*@CZU49Sqza(4MGt)N%sF!R`hd>jA z2ej~S8Hw{k)@?8xOP&rS2lBzInL6q|0`Go2=K@PZ+BxKdcQOR$vIP)zx}Uqfe4_d; zy5Cuwk5n^~O`>E5Bf`|EaDM+<&_+EkphKr)cXI0kh%CvGy41_=>R^TW zsvZY(0@lfy0=~V3*f83gt4!)=z90&SpmXXzwu2Y@ao`-I+%cnb6l1q&GyJXl^mG*cD;X{r&AIZMa7LHtTw z)y^e5UIMBL65Joz%C06T6os33!8uGoBT!a}@GRtg)`VwAL+&tACD!Mo#Es;r1&lOI zL}YPbDq+}2UL`TQKs2nmW*~h)s@pX!9zWCAegOI&9ZSziG5+i_VQy>=r=A!eH*lpP z{?X>cLGa@($f`eVJfBxIU}N7ao&zesZZi(w1>mZ6etd`9pfT2N%$@)S19(G9lPk2G z;Hj#^!VDP0(ALQcgUEW@_LERcIbm3Z&^+Nr!b4OKP`LI3F40 zXpqK?@;F0DcvTDLt^C~Y#`OF^GluhgX&Fonb6Wr`P0+9mwcOPpwmUj11h+8D+WKK+ zs7k@pw1~sRiTw-rFuED75*j$1s2A?=y? zPqXNt#(PUoZQlHAMwR}#6)*NARa_o%FTuII1>9V$cFbqm#94j4^Pv#49TECgk zzP_wKK&zxyUpE0hXkV%N4@^K>Ro*=$W=~(wW8d z5&bAo&oZ%)mIa2zdCb99l}v~>XPQfsvi$bKsf|D@`4v9v@(N6qE3 z!+Ln#Q{PC00JFq)v05^{?DVMojEGtoANJ_bja{p(7W008i`*4oEI#e$1cB+C6=axP z{DWG#mA7Amj5?8vJ*&&@!n-fM59D)95Xqazk3vZ5v{qHnt(4#`roa1wko(|@lP~re z@Qj+Hy;Rim=nDLcor1t0Eb?npCGh7{&0d@IIuKYOMZo*Tnqjvm+9g89C zV$#n`1mmwtCy&dz&}$LR>*>Lh%1RGCvqv3(CDY>O5N>}w4HSZ4>S)=%jSM_F)k^km>O4&8 z`SwhQ&bedOw{J`~Yct}%m4&gNa26ySY><_z_F|MM{hOGaqH@fY8BcZoKVhs*K=pP@|Lx4%<_^xw=k)l^1{V|myt@FOBlzr9 zqNkOX1DhQlbDD&$=(#m4GZq?J$4YED$5^#WnXSfh5%xxfTCn50&g!FlMf`~=So9?Z zS2(Et9WtQT=VNVUZ3{XHr-Gx3S9t6NHQD{78xmD3!_5$vKO9KrR=&%}@+<%$FlzGs zI=+B2?dMFtYq9}={k?~EeOQW$8BY;0?871O=q0{7zj zru)M0&UnTm1=4+yD_6SQny^b_kAJ>2+yxS-)1_s(2dJl^5Juw?c<9F#h!6{cigQX{xeNdW z$B5Ds{ovgC&fkwC zm$nDBUwQ35?tXqB_n{H%>C`Vhqut8HLlBGA;%|6HS21d|G(e72r!B8?=-mS&DVqx59daDoyiBPcaKU%Rc<=o!~2 zB}V1IPgpN;SqpJ1ai?PaFA2 z@{-B}XqI}&$rH)(-LTo}o@2vR0>nBCb+xZLC&AFF3i|;7q-2z=w#}jF+r#TjuVY!0 zS>V<~z+=AJ$~8yPVH;g^x}{)bJV}DZAX*bFB2n_BIQqA?kOhE2a{p@bn-P!a2KntF z?z;KO;SB0ev#Jk2vgaJ{zBNB)bBdg7rg@J^+vnl!*-R#E4}0q(WTCQT7f5LJu$dI; z^;kRW$M7B>SXm-*Pim3e+=?ClwPG8%L@u?Mjm>ZS9>6#0uTE)dHptI^=7=w=A88qs zncga>;cT@gb-BMypPf-WZ&N1rv0O~UHA5(@1pR75sbSeb2Qsn_ajTQ;;~anRDzz4QF%(tG zQ}&?TrNSZioAs56HyJGC&pPlz7$`uKpzDj5SsC0LxYc_}43aEv?icZTbDCRtGB>Ke z%wCFtEJ!^!1e+OnwWB6`w(>&*?EVGje(W=Xs2klrCfV)=;x66ZKmyYdYOrPj;u!}a z0!9$;DT-QjB9pO&?rhj*zqpPE;T%)Av=V%<5iVS{~Eev4B~#C%I4%&sb@) zo-fz%e?wO$FLBMfPK05i-s^BI%<&u~b)fD6cDQ=6DZN~<{sR3(ChYE9SS0U)aO585 zt7W(EC$ue|0}(9DeIPGNBJ$%GIAT*b=YzLwsdMa3M)P=6*Fb~BjA0GjLIS9kBhg+5eAj>DB>j#sBlg2rCOz0q8t8##TphUpvccXSbB9nHU9W1ho>_KQ!Ci9SfdH)bpq zmS4`^BNvIBVR^^K@ksqPdtr24ZFup9%scrb%>mj$YLmM&)zv`v5cHUE+TES7g8beJ zR~cPq`KGJgE~qnZukM)yck!L0{#3yx;H&6M^IBy0)!;e`tl#egFrR?8e8$G5*M*+N9O=|itMM*#E zLI#_c^HyJ&(3s)56TSAkHqB7vWt3=@Q#G)eX?^I6G*CsEV-r)JR&NcD)d2Vx8tW(L z)cGlyln0MwBi@TbaR3#+B5E9hWO?x~o0?j^A3>4P=A18q1qXv|?^IqWA6 z>Z0S-;l;Bi>eE`U^YR{WvEEC%#)!a-SWkK)xMini&)-x&rFy&Ttc|tvKx`9V#TunH zBd%D4wXXhb7H3I8>-HRjIMHBTNTL%yoon4c)+Z@Z-B$}-WQnKWO|yCex=+EVa*+O> zFLt-L!|R2>sE5+fv|{ur-vWfOjQ*{csRI&}3?^X#Xh0+*o1513U+sEyUPzCJJ!`_H zDp6&!HZmUD*1`beyR^N1y@Hn=y{;YarIeq}45;dulcl&xsc@lh)+D+^znMPky-w=s z`$1SxI0pZh+59H|8(1(v>|W@=8g||h|3Y|}hdd)*224s9M&W0E1eLMlQK@=3QZ~(2 zPHU&J>|d$T_BMxpetmhcQwBWFYuTl-6a}#4ro)&|$OK5-NrC6JA6+HP_~zb6S(BM( zIBCK>rLvh{QP^U>j8e3@Ldsp{Ca}>Io6(Ai{oTUdXJ zTFlYpSKBL5tE(1}Xza`HjetV#&>;t$p+Dm+YAcK^j<;~QcX%N21b*m?PxvT^fx^qo z{^C0@-P=57yLEh|>zPE-u+gE;sSs^bj5|>1csmuPo;uTDF>!YQk2U@L2p#_YI{t4^ zTOlF)+xoR_Um3=z*S;<5;sYuBy9c$|B{rPc&ITuRW?(6kbZS+^N^k5b*#dks{UO-X zCO)7-b>R5%k|;W}p6pPUDY4H&s?xZeO-W36iZ;l`5-@cwl4I<19j?hzPFCVQ+H$BHsai-(~Fs zzz8&E2m78#`q?hJ_#6f&zqK2f)TTaRex3b;>g-`o!DO;rK501l`$}TSY)zSc3=rv_l_ej)agCID<1+#HvgzCeOo^Y8GS#>du~ROat-@49DGhsd`7F zxt?Ii3pFL^{Gh@GRrS_ii{7fnJX0Ym(MMND7N#hGvl~LweKOehjo|S_bIqz)#l5AY z1N%EJW+1!1krKxkA#>n%*V~Wl#Y>4XKq`&qd<)*8a4Qa279+-Us6@_($^Pb`_}_z& z8OG36KdgD)z&16Mz3Me>NqwSB54`B-pASuTT(0?iiJgOB8BdsIP}*JyVQf@51Mg)v zS<`FFuwTF8#6;J^EB*h>a+61&d^wFS<|M7S&#xIOvWMWv&X3rT7%Kc{9t*nHTp{X| zy;q#YxB7P5e}4Lio!8|8@oiP!yrRR=6efR&kD^5f#!7@EZjW-vo6f{qd|w`ZJw|^C zL{&PK*h^gj*7B!|{^q6B6Ka0e?EW|Oq=FNi>oWYDPOBHEbiN*>E?dVFaVsp(6=L-B znm%`BmOjWna;^UmREo+Zt;IG_@M3UL_ZG_#)Q+R|)DQ5t>In9A$;p(N5eVfe4*ZPA zqeS8e)Pg0e>Ai$I)j^$pbrb46^zH3;kAY3v^Y&zIj?t zzdHxUw#A;}#j3;10}pU;(LY<}f7sg_)Svo-l5Nl&t5ms}Yw&c(^DF3fZ$)rw8H~8b zDfBt_03bh$sB7l4nq2)clJFvn9*$0h71K^>X2G*n_a8`&*%N?WW{)9xpX_5MD(W}r z!2E`Vb>oat(3}`R*|)Kv*OSsHI(xI05?biy0W^F=lkm#*{!z%$wKF@y+w~7Ol}T!7 zS+d@7$2$UT5T|0%Lq7<1b_U#^P%PSUF?+3NOQ#iC@BggsI3iz_>t<*M0v9yatW%5u z}XC3|f5ejKwp#!Xoa|X-2gf3PpF`t!IOWS@nuY$JE z{GQd+5xwcfKY7gNC#6`}MEpy4%Sv!bOwdTD2psVG!9C%Mg5i6k^i?RUi&?cAB&!x( zq>-6sWj@?~GUP6u<)xRp_OX?k$TUG4jx%C3!a#)qj^Xf$i+j_vNNZDmArJv}uB&O% zFmRn-oihMZd`t7GHC3TE@rC~Zng~LGVGR11)wqaI)elEJa>|n;kQJia1J#qu#s@9Q0{@*ETu~wVa{bFy%rzhgBGriaCv^gu~4Kyby5Us$!^;V^1^t3~F*0a=6)@_FiJUM zttEHXXP!^Kdhb;b+Id7UL^VGmb(B>B+{K&0M`_cOptDQ;LrtX{WJ%z-yf0Q~HZd#D z0GFDWRk1}P-plA%E~)1v*EQCSUBoG#t(p&oU4k^xGL0<8TWN6Wg-ZB3ot3p%F(XdT)N_YXb8{`y!OzA(qG}4FF zJ@9}4kFp3EkP7vn*zInsPCDdI9Q@y&^7So@ zV15cPMLoAYFOv9mIP>%I`N@85=-YZAI(C(Uz4Z_}EO6=(;mx+gfAqQGVT)v-g%?8( zHb<)FRY1+h0u;*4LYpUIn0x`CB-2x5h_#}k=GCnIs=lLvIXH0c6$#(ly;tApqCbRV zv#BL9;7lc<^yP;amItt^)a4|Kt|nY9sZ!FX#g=gB`PCO!?;>6Hs5iB~^~{|*$=}-+ zfK!!+{FaC&>K@9HS!&cYR~8#z+TE1*q^46H%}H|H1o3vjp3m9Bi0ByKhkLB=*p`C9nq8)(H7) zV;NOT>^V88)Q6|JcC*bEyPc=OAz{de6pCA`G)kj8pZA}u=LEI#m7lTvw4>y1U zOn;>gp?-AM4+ZJQ1h&E4Bn&7kBZ#AVBJpDB<3{$)E;b3t`uxv|{MGJ@8!Fxdvmg~5 z?c^9PFM13uY<~`ROC{f^kj!;1#*zl@c3>cUGLg76 zLXqYe*wWeg;Tv7Z`F^w~iPa{Q0<(lI_lg9))AUWfS_oTkMus=qY|CTD{M&wKF6^h@P&$Z-)~UnMF5|lbV#vHsRvm5B zE3AHWqlf~+P;mL1u=z;!4*FTxLWqz(*>c5|EyAZjZcX8I4$C5YK68PVOo%IXCRs#%CB9OE!)OuD(S!EgC^S)(5A9bP&L6gFiP{tX8*eXQ1rwPu z61()c$|yqh|drxuCc2{!UVE^892HoIsjBRA)gTVpIGCy z5Gy)>Q1{yRKPMO|lfh0&JF^C8D^~P8FjG5*3lodNYEyhlMH;qprO#V<^JY`S47N_3 z1IkLr-9Ot|Wma}+gs4YjGFVc`k`V7{ONV@!DEvE-)xlX{Kmp(N%mPj*%m}yAW2MJa zxF^N9Fe}uN8JiQ%JAs!ePzY*8<_j}M!&=c$V(TitFR{Fet(uFV)UJheJM5#a3}7#t z)^*(l%=`+ov9iV(!W9m%+5{d=KGxbkfb8iL;ndIKyB~<9!B@CYCw#dBYp(@t$4?pH z|B9riU(zk@S`xl^gN0pCjUb7 z-~sKtSkXb{99YaaOR=?eO_-U~;h4-LOT6}g66`r z=T4@c3N)GoY?(d=`}_M9J4r>$`h>*Nw3DK6eDi%=iT2x+ zf;~LG3C;?*F($#+Rp0e8Z!mGy>B{3>rYzedR6(;#2y&2reoPeP~I4 z)`x?PAgfVEhiR1_d+YJkECpzMZvUKP&pX z-kAi_%gRBZKm#{((Dw#P2MkTT|5XI0>`v4AyNkHgYWz3sz{9=>UdF4@py^#IA7Fba z(Ra2e%7$@_8B&vn2f|(WeEKYwns3J!dIV4{=oFk^Xcip$|Gm@joUS?b?q$Yu4alc^ zh`{(%Brk*B6y;CQI%R^h)%{Bw7XcS14M>G>{#U%cYwDv&5LQK^T2Np#NGy0JEaB&6wqU7e15vw3yiHPLuKb(+ezt> zdX6|b@Ca0sA0pWtao`~%QSP2zB11r4E&#OD!h#>>)way<|Fe@!+odRHKa%*@uz~}5 zIDKee+$b+{N|SbuMzUrb+FloyNN*W_-YGiznTDdr8gd)^U3IkJR^)Ok43#Lg@VVG1 zsy-@2;+Ua@Zh>1vLYwYE)+gc1_sIpg)ZN{GX#>s?4BZy!0v8Eaw_3oU`FAbDgY4y; zM98i_SUZ|eEI}=YWF-SA`vWlmrSO|c6CESx63F(HyyGaDMWaW|~RY?CFSLHKXTUZcO z6?k!|9^?b46WAprS(<#sw_++N54#;C4YX+d9QbarVO=V?Q0#*c2ezs8=p(v4@TdD< zN~&m#tUiUqJs_vg14gBrK%syOtxd+7=s}=PHnc=!r#E#yMd;E7pPns6xr_h9^{qXc zOAY1OVxg(P^=?SVD7-Bfu7*X?^5V;+>{;MvSpPy#C6Jn`@<0TBe;c-%IxYkn)niEyT`j!B0jG=@<9@BP?4M2gASnn`4>DEY z44sWkLPZH8tqqq1;BWi*FTV7u0&?`5?c<8|!z4AYG02_8eq7{xJ`5u$^ZltYn8QLO zV{jdQ5&_IWcr{fhGxcx-Q_*YSS`7XF1hgSF829xj44%d%kP zJj-N-A4h(~k;lWDSSnF3ObMb7P!3c1_u0Cp^+VKK|DiTR5f5MKd!GA+BEp)QhDMn;|$K1p~C=fU!B#>~^>q zgTEI-G0JE8t&jTrZ^9*Y9gp9QSTFAGZn1Bo(KpmL@Tx`gfj`Tz{t`PufR~)~xo0 zz?!-LUoSMQsEhDT!AK!(`{kooIgpa5W`x<5O8MD!#^ZWJo&W)GxMhXUhkV!Ks*N%YL&-|zz50cqCDBDI6FG!UDfA* zF+!3*F+^UO?Z-||W_h9ri*7lIm}!*V^;vFO>1ikHOxu)B*Cwz%P$gNh&0T!5O8}4t zcbRG$GD@|~vnu2m?KI|&qE7(~QRuJmPD*fp2vR1M9+Xht z$Dq1pJ&}+wB{p{+9EkBbNvJe|{EujNB#j&mP$PcyBg>dFz&M+Z+Z<0B4mrcbiLTYIrnsoFvO+AsiRUW>0`POSgzO$g_|U;wv|Y#*u>Q6k6l|m3YR-HaFVL z3kzb@>Frh9Rz3n^xx&tqr5ubiEl{H`Tz<>L@=AGZ)EcO%dSh-)K*MxxV>?zeRc%eg zR}MO?tbqNRRJG-R7hLM%DQGK}$++G{?eXk8cx3xsqH_NyBPHMw}`z2pK0+!CIZ?O zA>~C42>^*mgLbcd>g_);!$>B#VS#g(l{>4U3oZQpSlEMGGlG_WopTj)GwVJ&^qkwNSQpfo6r>as z0LW}$om=eMDr01j1Yx{;fn~8oOK7OOBUAI{Xl^j;rG1c?g&cu04uCHA3n&z}JI(Zf zlNzmpFjn7wMGS1nC3l!b9Goj|efI>}!iy)Y^i+LH0lhwTJ$vEqbSEmQN#X-I3O~t# ztE*t!Rv#|<`k#3ZVffr$hN+1dezcfxOG`oMvGpG6D4X4Z6P(+scq_?nU>uCq+U|%` zS0D%DhN9vn0INZ-jKzX#p_$~0f1jtnQA>$GgikDXMmS_}2maXjf(Ze`e}A)_cpOk2 z@yMSX-1Z{qb+{RF3XW_kJSIYiy?6FTGmg3!Xx((n#KT1>G}FQK5~e!uB5ORF0AssN z{YBq^xBjEONRw~Z6?Ti^e}1uwy#qZ(35#wSOy$Q>Tz755e&yRBo=f`?*qiKXS}V*qh%HTw)u4i#2W7HUF`@NO zW>N{eNGmPaQ25{Mp+CIfS)$w0VA z@#oZe+{@L77{$!F*WsF3>tH$ECJfWW0|yrG)$jMP&YRfHn#hHA$;tIlY=v_W^os;b z8{|9zU%rbfxJufDDBY{6cQ*T3UCm^ijTs*st0XbG2oN#BA=LX)3cV>5H_TxTd~LE$yqK?$r4CCa7L z50w1dD@J%$sRG|3viaMiaB1_iX^_?%9iB;W8OK&+qo4WGV=!4_-Wn41>OvBigOtGz z5?JoBL4B>!Qfinmx^SLa_J4`SyR)nu(vAel<(GSAsIh>yS9o}SlX+GPynXh;<{=+Q^xxR%ul6ZOsB#!&s zw~w2cSPX3u^iRX}3O&??I)7dl&xAtA-06RZTc)eRG ziXW_Ge^xv!qF`x^GlL@*e%;TOf8){FrDK zMX*{7kptQ6u_px40|MoGC|Dh{CFBSyZ=YY$`4kXuR4b2C7A6r;t{SfoJ1TsuHha0l z^pOFEEueGS%y@w}Hs>GlSb2?-D3l;&E9UTwX^zu;{BatzybcqB?IHnfLL+{MfF8qP zoUQ{u4J+x<=Unhd+4(s(%1rxYS7fUGI75GIBXg2h#rjDe+{hq)rS(e=Ccv6<}N>N5M2G!Rp~FwnZ4P zb)skkps(%u@3z5MVKhD$Jl*6`(Z%tBbLNLY5Z5f{gz4#23+@}Q4WE5eCx~Wybom6=CU$X{4#T#2Db9A_`+65EKbB2BS6Y*q-Jp1r z$_zbu>YA3vqIVxw!wx=waHV&@|E&R6IDV8Q6@3aBf~KhJ*FI^jJ@8E#qKZAMlktDV zDnpV+L+q!gdJ;MCM$AI`QEnZgEm~B`LhB598aUdLW3c^m*yE3?3ZCH44i_v10 z!~x)qo&$26)YPtQrZ(M84sh$HU?-W&K`s&S+)ft{L2E_?SmihmF)`Y36<$(Pb50Ke zK|x}JBsN}uM<#19thEYzXW3uc#Hf4#5k6SDi5-emoN$8DH zTZj?Zcj(4rqV;A1jOjK#hkGxR#G|$ORinCe$!myhmj;FC`pe!hSI z{$>Lno3+~fv4 z_PWa90%MW(b&*4j0ZN7dMj$_G{eEW>F$rX5&HT#9d1g3MRd>uPgU)%!Ugg*bpb(i< zMVIf_{i)?8_m=3lJJh{x;j9V6I%*C422`T(uh9P0={6r1j0qef?4`@`4{CsD*waM! zRMbWm9rQ2Y$s&cJx(C1>0?{;?iTqHkoR&2r;Miogry@OtouKfYWS+`ac49R}G@8O+ zKBRnGz4{*zpd{4a@#E+P5BOvy^E`0hA3H=(t8B`XcMyl`KRUVQN%I~)pkK|` z9T)e#fOdI!eLL7}O?Ym*U{BsZcvsg=6&eW=@06 z$ToKO&;g&KLt6q*>2=AAg*4~1THUD2m@QEC01R6elmc?(;*pJS&ssMaa?tZex3V${ zHjx?qf`TEFLy;;61F@yG=vduI4a)}Lh-`WQU>m+fjLqT?xF|MG5%4}_otZoHPriGa z5=H9EQ1NTZYY!OiByiO#Gd&LHm#u&5{fe_M&wOS6)eGZ$?s&=6gWd6`D$MBHizulE z_i|!~w}bF68@+>&LgpuBB>5TV+9 zHWxA_&@)A8+O4(GdeZgyeGK;JE4@uuN+5xCMfx_?&P(UqxhyOVn{(O|8(rO-0xP(t z%ccR!6QVMP8_-v#3H+AHG=tYV@Pw1(LQ)0C@NG z;eF3rd8}>$$755ZmUj@CGO>m4a`&49RWf)|F7rMd_zXB7X@rV|va?LS&S4TVZ7V>$ zCGso) zWZ#Zzj~231*`SaQy3EgIf4GY|GP(oPh(Jch#f+g?SJ$h*V+lXe#@X3*Fs8RawZxz$ zQ*z7{AV4*yaVn?-tilu zXNBUkPdn2FOsc8=$H)k5#rl%QA^shsQ8knJ^jVP1W4@0(xB<1+wl`p&K4i#?RnBAMnz(NTN+wDKww;Bp8S5vQ^aLq}+1hMRSF%R;}<~(_(nK$t>|~ zVSOJ(7Q3|x9G5O2q4(@Oh9^`qwnfNhf}O)FLEjv8gBm66_-MHB;Em$tiTnmyovE;);(tBLG{f6l_`f0}qF^r+*3V!gpN^<0Q#yLoBLX?2TI>d_pW8Y_lswKA6C>~A zz6uv`X2?G)@DP)79HRX*opti+E1pa*e^gbKq^ zV%e|EW;%kjk+D-Y(&VrlyCQ;AI7)u!`RfK0?a4V-kU)JGlx#m!`plr6C6bYZw7poc zc{QZl{ZQ>aY%2nx4@>M;RWLt{ONQdQcRrr!Q%B~DD`1zU%*W%w>&f4G@%X3o{#y;G zu8&1?JINyN)WKHTrL?j~ducI^@~+*KS2tLDFm*T}BOoFC>|@v?;sZd0<93$=0Y1T( zlQhQ##|w`8VdajHJPD$jPb`iS_XXz8aeMF)I!4xW9jRDrlc`L8;>~d0)HsovqN{vt z-PR1x&3!ii8=)0-hIsgB=2ce7P)IHgqtp1)B@ysLbP6Q#*{ORWQz zyx%+6B0d;P%P`jS^y%ToFqxLtSt65JCW2A6koG#7E?_KOCWeGs~t3U zH)`mA`Jt#ACxXyX&rH@Rmhx1CE){3(gKPhbutu)%&~FUSUWZ~9%;pcgUo@`wo+TUq z#-A+duVhaHMLQF27DMY4yVmO5fi^|%T%EHKHcW}oJus-iy?m)m%T2l`rjiopTUc3Q z#lrjxXdUDTh^fyXqH-fK+%#M?==(eRsewH0k3F7fXIB9 z#*t}957QR#y#=@l&;+pC)DO`|Dbo|TFvbkv#3g$@pQWTEJ4FC~a;cr+q0`!A4;ugS zo~2U~I72-K-f?0a21nn|Lc06g#Ag3V`UQ5|YysVK;QEy{*r)A>@4c0*`S9U&v|&~> ziuAAx2>fSJ^mV2`D0qqyTGuLB7OlLUlPsvtoNltK+ zs(6rF8a~2fRRLDoe_e{z5-KPlGBLWWbF zaQ9hem|)70ab8(#m_#V^z-Su9fxHtfI^L$*5Vl2f1d0Tm);hg! zsqdQyRx!}_$sFWMrFdm>+G=GJ#!7=RC1xq!QW@4`0mQ+RVers!8t$qjl-7|h!a;cg z^u&*PkaJ4)=_1SZn zeT*5Knt0DmyBZ!(`xJX5Kxo~33z%d3pcUDCMKv8HvP+Mq6+gbpl3w;`xD|7n?TQFC z9yx0?)k7kcWKs18FG!g+NSncTpP3a7E$UcJx1Qb&|Ac`?je ztq}HVR2j&7)n*H1h5Ml+{xl`y%~>9M3VKWBUlMfWXI%vBb6gf3QH0k8gXP!-)e%>| zTRBP028-iq28{{(1*&+4nOj1&u~x&LJ}eFNV3`%*Wm&#MRnb6Py=O+7nc)+ZZRvjP z0>j0uA=J+sha@l+v}Mcv{(G^i??i!s1fW_a?&0*DngA*+)qOito(7Pp{s2~zz!SKg zJ8011qEyuF49HsL^i7g z^xJVIir;kJ>3Vqc*Pnu3mEW$rY1|2EuIkycx`0{7oglQ z3w(VH=!s>}AgY?c@$-y9?+LVn1;&hWExhdK2&?ZOUw+)Isbx+b+ zSKXaVw#mMM`rG9ouWQerPp+#lXcz>BAYK?%Vcb66VB+C9O|RIfM~jwPp09rKX? zSRT_Z77%MQ=3M895!)wE&q|fqFZ-gY@OYj~hW#eEc+C75MGZ)wRwAK8Wdi~p*7RC_ zuW8#34S-TKO7ZEP_I=IkgueoJ?y{rhC##xKL2>k65>fut{A)>eYJj)z49zTf4tNY; z>bos5q0s2q-g_U>GDiaB6hT%Z(ZkLbXXG+oy&Ooj~x+Fp5v@lP7*#( z=Ss$_NA+_{58F@nMkn}SByA@MuZ_sKQrckR**^CUMBHu6KN7+)*>3w#* zMT6_Sh4RtdSvaXJHFm#uZvAKV&ON(>54egBJEwAFBWdPH_ZsyB$JB>uV~poO9I9Xw zV5;_`%U85;ec2I%jWvrrq{16GY0Zrdf>KtOLCHW#L5)GU_cPX*%)#4pUYUROFqyVZ za&g|Y(^{O@5$I0+(B3IUv|xa;$7~R4Gkto7GX7Zc`O|29sr?%IC{Ew^MKXfZy}5je zDsshvZLB_VC<43zu}(v44Agm)vG~*Q78T^PveGwJJ|L#jb%=y$4_tT8(dzU_(vL>Y z9h@uo057~uy-&C|5$y15h%UeozpO_Zjyj6&DytYZ?}QnPfaRI)1KDg(`wdCcUe&5` z&w=5@JO2eDsRm)_Fj==oEtRl4N6f(h&FM7V9wd@d;Rywt8j)9wZ*Z)-V37~Y>>%KM z5KzEY!>O&7Oahwo7vY5;Qv z`I=k&`LO82<;|zhh?UfWOug(Ie)U>UmKJzK&Gjq)10kveC4l0A`lmq}1Nq&;vK`_A zsLkoTqaI+oBwsc5N;B(41K|^5URl176=@afzBOPwqXcTts`9yXX@d{OTA9Ybfpd!f zN#oz~;E1ht+4S&7({KEdbsaH=-*LJ@ZOqzb?rgLHVDoGK79*R+;p=Pn%T)cqR}K!Y z$Z)||SfKV;WjvQKicTXzcR&CO4ZIpzww3;^);7e|{u;%599<042hWJg`Nc#Ldt|R7 zM~TW2iEZ>m75ehryZ@Cq#UN#|R!dY0_Xd7Jjk+(hx}mtGIX$5|4NSAKt+a{2iy_tFot(ymb@UtuRneyPqcwLJfIT(NBlHw06EC=;?gf9 zg0nyV(*d$E>~h#|PkBSh5NQ6AuUjs7>is6B=+dOn`iCj~X;P_)LiGn1Z`q9^vLS#! zh;qUWl{4uzO8Tva%9F^I#*cr(W@YNUClX|hQp>z9Y!pCfnb4sP8H}72Aj7PrgHkLU z(mLaK$7{y*krUb&Mg28pn>)QW=K-|QeNPx5%FBCnqiCqWKTA9k zc_OuY6DBMNvi#4QNiLXeN7k*DJWQPbZTa=;`r`>+qIK_=wd0mKn&uu67Or` zUMfQwfB1NZ(O$P$7V2R^Z9xGB(sQ(DOqMikJ|OH}m> z5Ebk#FW5((YEY(K+?tFYqtvu5MU8kP5^mZ%dnc`8kzrS+{;WP$UfAb!AVjBM+db9s z8r=#B9cxCk;vaDB8OIb9xWB4l_^8mC`5F-b%6aOaffXnsWZP+LcLTXAes5SASihRX zi#x)K3&Z5=?B9|c#X?INq^PrsMw>M~KzZ8kK>)Sm5X_u9q(T)L=1ElxtA8~sN8P+1H$FP(17;oyn!Sd$x=l&U>T8{6iP{H_W76aNT zRP+|E+=o+N$tw9T4=s#HN30T$!lsh(fYV+(l(=jck?xa36eCgcXcO8Y~l8C$MP@srorO`B#608HJ-X*P zQdVqjpcbS10ZDfq7@FbnV|Q?(8Xd=#hK!b2GY*OP;S<8;g}nF5$bTwF@GbjWGt_^G z8oGe_i_>i#d=!TexRd(9s0}6163m&`SE&E8QEnn?c7y_<(UmH`Nw=s>&8%*xpK{&q z_-?&Rmaoh`(6ZLmN=UVx!Lu*ZH){ww(?TV=mHE7m#Cg<)yZUHBI=4DvuK6}ewN%6< ziv&0l`o^Qf(^@-VAmb5P_V|5<{((VJEW@zU>Nu3ZBoW~KXcH|PR9}jeT-Q*Q*$BU? zjjbOLtD{Ss>&TjwZY;{hIy4}{kqW%qWj}~Q>GdP<58GU=Ogczks?c5*7%K#uznn6{ zM=5#kT4aizZWfWg7E&&_i@2Iwh|Fxs3{neqV&L6{(*jIB9$skpxFQmW^GksQSZF-^ zf;2lroF$}@fxX*FM3(XwWK%$p!t&`W+}x$C6F5*IBs*38TFzK|}rC?O~uR;#=G8 zuVs3FX#s3N=d$a9E~$No=yXgWqLors=)LiiW7b1OEDtfrWd9NO`F0};HmeVZ2m^+= z8CXYoLN{E5QAUk+C-ys%%q+?aB)|X<-Z#@$cv8zou}$^~;FV?Nx-pay)PCAP{F9IKAvH@G_L>anw)spXzyFa%txvK%2SM4$6*Th7 zWJC$92D>Y;5pKg(EE9ON-w;@z!P@{BwOBN*G{(V-!6?+OXq#)oWunBv9k|MqvQ zJvRzAcE%#cX}?ep%2@l#B`(^xrzL5C?EA`f;bUC$hi=nyLYcpj=p$FjECW~6U9-@! zKJ9|`*{&N8@Kr0@wuXL#gT+vRffVAB5x4yj#G@;OCQV!SKtn_Dp9ln)9^pdMz;#E` zg?wa=c&7I{s&pK(CXiRS^qW2B<|h!H-?l-J>pGKBrknJEH^ANFm$(~ZelpbQ3af+? zXQl^aqdt=el6G>9&>N*aO&-H0MW z#_bwdVIv&`fOL&n@rO}zRbg~y4nyUua&x>nu_A4LA%bSC z>p*a?A0S=bZe%As?%{x$x`l=bMDw2TZ~BM?t%xyW30BMDc~+eb5Lq#d!m@L1U3jSu z{ssAb6zr?L(nL@8&IHQ)r@D8rcq)lIr$fbvoZKCSJOhP&pPM6lzc>W8p8KF_q&=iO z3LB??A=`b2)1|i>{7Nru{ejYyofN^0LbCixK#ay7OU%#YwvAMVhVA`W-*F^+v5xlr zTQDg&TI$9I`ze41scb$EG;mEeb4}LXQ*_EHHLBpfHhn#*pyIL6BPRRK6*~G$e$zKF zAO-xrXQw0ub=#v=FUuA&g2n!Y767&}NH$NKQAAvyUL}S8Fq~h$QK9Vp$H|xqEcZW~ zHx|T*Do)ADr|rE2fwFGl3;N>VIU_vjF9=({c7%PMDT1xT;&b%e6FuU$K!12M#q$8G7>3N@R9T`*7)@bwsc2^C)jIarnh)*G>VM7Ir(RPtPv2-3 z_J>Bd}hH45ggYt zRq`n6#w#)O*#fS9ezM8?5i$XsfkLUo3c>GVEKX~ zvdNI{+HaiN*Obo?7e9PWRXq-&mGBKtSO3faZ%VWUEX|?>E*-xRncPUjMZ*;SuNWZT zNDRU*RX_@C2bL!5XmKDrsn}c2kfZXMJ>ZJ0X3Fi$~cY z26QXn(}G(zsLB<8l)nx|1`sWJNG`h0h~ME0N1cnYhpps5i)*_3St~=AtRhPf`fsO{ zxa@2AT#`Qrq?5T+Z-dm!WF7HmI83M1j+19JuyY>nh$wOvj4?Oyfl_9rM z)49Q&=$Vx=%O}k+~+Yq zmsp%RfqnfM(?)uH{HU@bE=i>a%10B(wpBZ+*^1H$EzV$>%4K;K%_pz? zrKxK_^tYEku>aZ{@7VcoPq^cYKk(egzw9yBeE8wN9KEmgcYAMn+UuUaZTiMv`1=>$ z|0Q?6(R=lOzo>lw+uv}@>78Htr~Jd8y7A^;8@%n$KJnN0&!75$pTG1?fA;B%9(v6q zAA8yMKMH40r4Rb8=RWkFAHDcDfBEFTgYW#~ubkX=@)NBccfIFH_q*-8UjK)CF1q3U zr(X4$ABmrI^2dJg`+oG;Ex+;RPrv3z-uR|FUvkQcK6LyCo_n`<;@2Pf(KkJC{&RoZ z`QDwce%gsYeZgDWkMIBZ@4RyVBahznuopk?(hHI-a2?xsydX})-1j0sFACT3^B{H# z%L_9%E8@g<4dX#S`~0)e@=Jeynem$5_kH;Dzx&r8c=_Dh-|?3}{lL$je$J~t|JUFD z#1FpV=mVZ{%d39>w;%V9@1ObAyV8%I{{0`i=EAEloB!|+`oHz=7i~?y_MSAO)?$KJf-kKcCihQXdUKH;4|_XpFr#t(b=qX(Bxhd;D@NBW8Pp1l6Q{PC4X z9zE0f=YM?bvwrHAp76(?`Qbl#_p5(n=B10j@WYRKz=K|P*$w&o|M@j%w*A~!9@UGU z`OsH<@Dc7Se!?)Wzv4~spyKzhfBoyi`wt$GhyBI{54($NHio0Sc~G5yj-$xOTdH%B7s_Awj_Uji)%`!L z&c9gQ|C8$cE7kcwRp_3bzpL|q)AuiWcy<2o)%o7){A< zwCAEftye%<|y?)p}POx>KvUZ z_22TL>U@eL?YV_#tNdH4`@dbCKUJR}5WbZ9uBpy%s?N7^8sZ%{q_+8G0?(+Orb^h?`d?!ch`{3iM^WD|C zv{Ul$<49c}^f(HArQMwWh8*Qw=tlVuKeIZQc5?qCPvR)_zeC^u$e&c_&(QaOYl@@P zf2Y3xTS5mpmwG7wTNX#D|5^I}Z||bz^ZDwWKB)6PN1p#FlcPL;S)cz+-TxDullSj#;&?sxPpbPDD882br}X)y zCPz6xtbKH)e~)qMP*FokdgUGJ8e$ zMA2O-W43!{vS=2IbID>>?38AE zacQ|v!TgHOa$kNf6#cnQ-rHV1XREoq*z0$fv;K0ITKhC+D|vdog!1<+7t2L&E6?dC zY0@it=G4s74qQQP=AjP1%w)cOyx1bun+u(8(Y)e{TZ+?WStL?hZ~GNjm`^pkMOL&= z6e?4%Am{YnU9KH?>H@!g&+*J&|MYxOcfERiPfDNcbdS@e{v6p)o5$Ofr&nWbme#HL zpqpn7A2Q2McOmKb>Dy?v*?iLLwae4GRdxS`s6G9(bh$kbLCvM4%Sh1itaqZJPo}nP zy}~rjJY6|Ao6Y7HX~UvCZN7b`*lK3o<;6^zotsPDP6kPJ^-0g{&k2?0J16vA=D% zV%(lF*Y7WF-?r`K$&<}AnNQMoznOIwwk;NY8TUr7$d3T{MLZ>fcr7{>65`oy;Q;y?!!3uVrm` zU(-J8&qLm#SM)1Z1hY3q5ZhT{-mon%PHbCTo}V|J8=h>N&v}ly-Mpe~8)FZ*)_nMp zBs(qw)kR)UB=cM0lfJpUG}}#()ioN?Xe@Rb-D19zlvu1rWi49tyQg_5gVx>Ds0ep{ zk|a7>><{VkEye|pG!5gGFE=juy*FW3KLU0^ZySGxdj15*?=*~qTsOc4&%Q|?uepmO zxZ(QCI6m5V@QZ)fxZuJg#)S|3q+xvFlyTu#ssEp_=Rav0#@k+JT=3YIVQd|cri=^k z<$9BPes|8e;LUd#7hmvW%1jzRDP<@>coX^VqTKVbL0sF~GK>%Wi9UbZ50K|kT;ur3 z*CA;CY#2ZBzks~d_bJYQ?IVU^Q2(LGFphDp^?bvaC4KZ|Tz?(5=mprHy9{IJYdIb? zjL#vj5Bdk-Fqq*xejGUbFPJv!zWgoFphced0DFI%vZqMYd(ppv18?T{b%ycq-THXR zll1Ws&*w;Uvhr& zPwL~P3;Ot=tMu`Twmx1`(dyFsRrhDB>!Ch=$7?y}(BN{gG??V#@732YeWX5Kc2plP ze-lR;hj$r<`w{XAonB`cPvALE2J6{>VHi)NEq7V)#_imjy7%=vJ}dv-`}%u7JM!P_ zfBNh9es(gA+#k)msoy+l_#eMtzy5!9yCm0W+W48Sf3$40KuuIr95B_s^DuUKLF^j@EPE?-iPUJJMo>*K3}iJl-8dt`#|M z5_@@QCstwGQR#}aT)k_8WQG=f&hDC7(rrrevt=u zX2+p#rM{o%gg^tg@C&;LW1kCtn52$h7Ix;9ejHk*UzSPXWo~5qhV9~VL~fV_p&fdG z8%9==x=9*`rR(~!Z%47^1%B#Ug%jkN?__>v*`b?Sw(HSCBQ6~$bc@^%3d_nZKg|L< z76(b3I95=^nH73POmRDQQ#&hT92+kW+}tkh+$mEd3W}r*^Ek^3+kzsI?F6Y`B%x<} zeo~~K>m-?<25xCN{3{bDilQ^!xD(hH5u@v<{yxaSw$X|xtn@Xmbq^18=>R6Zk}e5=cFN>utQGDytHCM%SGuFNkmPB>qQZ< zWy{aA+_RxV?nGG{1&$H%Fvl)@zl@yND*Q0=Ez9*YE(Uh#+es05VG;#Vnh=`~t;BZ1 zk~ZbBZ@HnH8L30VgD`2T@?Bc@&meP`G*Kgc*cngi}9YZ2ZWF zNQMy>IV?hNEH5eJG$>;STDxJ%5Eg!#dOWcV;-W~>%udoEP3*J`0y~L?rVc5(gyetU{KlgGsffE@Z%g$0SaYM&;v&6H4)Xozd@>`x2dsb!>bT^E|;xhaZ2RUtU zU?)$wtBCyoUJNoDm$ppZ!Y*SX9k!p9SqViFNDGIQ)R5;%J;zCXC-I%!&m$|d_?7X%zzPGn$M*^k zdKVdaa|Q+>3!OME9V<-@%ZVVNgPeJ>o#j!U$0bscWu8lCy}Wc1q$h_p;a@w;LOaM( zpYnO?Ahxk##Zb%7QrEM{2bJTpgkv*lUub)7kUDwddTz!zc*t>Pm2Lu8!49dDM7~iJ zS;_xtfTV^VHQN>g$D_Q^^B`Wv@D#BfXCm-r5?CVEsSBsUl(8KcWn@7`zl`I|Ej`E# zABMi?yF4(97@9DFgjN_jmKDWG6e_Xxg3_l843bf}76KNP43=l-ev(?D@LX9ymBjNx zqzAFj6Ij#TL1HIvf(rB86ag<2FLfakVGTF*5L_pX6NW8F zc)mqnEp(KMdsws}fRh6zci=9#+43_wj<8Y~fp#sIo)IO1$%4qTQ5h&N2F!sYqA(}| zBl2lz=9COOT}>?5D9nPeB+i1+I9V3as3J)+L?kbeNYojX(Eu1f@k%4MoFvG@vTzUy zh5_o?QIuz15|lw`p@_X8M;!9fre6ic%YgpFeQ*J~#z+`B-zj+*-9$ZGspX{>g9?xP zv>s;jVN)c%umj(U>@;vZ$IZnO#B{W;4=A@v{kxX7z`T1!=mu!R2oA7N%aA z+g5^flrG#AyI4eW(|jMZf{iD;g*`)shLo`a*M>tFKJ=-FB-u!{o23j@n1li55{ZJ7 zt+>dtJn&-!ERdn^)53ud=^xm{LHD6i8RR_9E&7jzN98$KQ7l^l1>kj*OBOj81~5|L z_&zhjt_Zyi_z5WNCqB_ZN3?6~hb8|37JOs{E$2mKwUZzzy(lqki%~@kp(q$8fO9i2 zhim0YE|v*%fc3X>R2#-BPIBxxtcc`++t6)}QG!D}A6*D9CBPgMB^JknK@*?pYC$NX z(g7D@5kL_+JdcWuQN&oe+<-ulZNn1@1`+g@+Hjn-#w}fXjrvV8lyyv>@&LgveNn2 zgel+wb%OjMk0`nnt6D|{8XFrM23DNMg=b(zN+0g_-3Xm504Wba0}0j@SYW&8*8pWC zV`E!+l-MPx3y77JS&mYK58^1LGm$F{;sjZYexWaD^gISr7DSyTi?nE1>C*kaRb6oK%Y1XT(XrVLXUJ6 ziIWC}sEr&U0`Wi%OP&$F% z2tJc$8d;Vm*nChp0$%_+91lvuuYjKd>H(oVgc%X_tr%63$5t5#G6uCF5?EIhs7qU8 zVU?*bt-!B*qpoB6b4ei2TfPvI1md<4$-WJ`XfxL68{pPy2n~1M=?K zEOG%2WUi5j^~OmH@oYd@+!Jyd9jX>mto;imMn|$6QE*@ zVNur0Dijt!WK5k1!yX|^q(zGJx&c&Pxm;e;X@z5zx9$)eQ}cn>%hc;IJT zOh+gZ=MfhmuP+)m$2rBpve22Cs7o9TAU`dp*P^;{Qy6qBMe)%m@D-ZR7v+gqVh3oc z7$ztp5K0;pfKGgXUKHa#SZ+6r@}(`#o#mOhg*lci$b>jG#6!-qv%UOBuEv6;DBb3f7rHQoO1Xlq`4S$m=Avo z!GJRYND+o5S^~I)1qRLtG4OCoSXmS#>VTqj6Ar`lfi%(>gcb)_4co!114W>c00(#| zKIj$Y61g~7uHi7ka2ukF7(@U%x*o+Cd}OOcnV^Sq%q@NtZao5+g7aVn{1~)H?q!CX z;%$QnKofZUIP?~ud2zUh+=ipM*54aruun-{TUQoB_EMy6^hPiOC3^Ih+eN-4eJ`<}Y z9z>+{Z%zaQWyL}1618+S$aKMr%)DTG)U)>JTfN1^1{_q4-S}SBu8EL=<1~UUhgbXkv503{1FcXQ$d?Gq97#_KR zJ4D;Z6DKwRm}WJA%ZSq;44;jH#(YMWlfhH;4nLeWrFdJ)<-%CS4z3C=FLoDS3isa4 zL9v)c!~>p$+Y5p;$N&Qkv}S2W90njlcnsVXU?Lo^1mrsa4x||O2mJ!{$5Fv56Gj3< z;Rv~jX*-UZBPv4fd-)O*hr!P9gt!U@3@MKn%j1_-cf4{4fP=LR5k% z9v%`gR=hxhN{C<%&IdEWY!N6KKnu}S%-6uiqkRMt(0-T%Itnc0nV?u&hmV9Cg$B*h z|9I^}2y`?`7~BzOrGZj(P#g)pMLq-(2y_o|Ath>0JRiJ(RzQ8ofjU4`0WmM15l%}h zVk`xQ(5V6g4Q0@$MJnM+Ody&GtO|U_pT<{~m9UIN4r z?*zgENlFS5EoVJ8G~^kCXmGAXDu_1{tjIms0uvJxNy0u6T)__mz%nC(fg)G|1qh)5 zng}zizM*T8NX!-7D$blju*Aw80zILqFTe!q9Xkgq#tR^HMex8$QyVU#M-pv@f|x62 zOTbDLA`}CH!}rB~K>4L82&OG$5(N7Xj3&;5S5A3!rGmS7M4l)pB5uS0lL99lfR@pF zKprvz*Rse99D-(%!NSi3w@Rc0!sj3={$~ORqbtFDf&2;aAtHPZkQo?-4Ts}kZy&ah z_3gA<=p(#M=#1(UAchzpw1Y&&vBLNY;3GH>hzyQRWgfsIm`{!N6auyBK95(z3sSSk=O z9v12d9LjGdNzgS+6%f(p0yPlcM!8@BQ;Zf?9;lcw*#OQ%ae?<^upce~c+kUEAVfGH z^aTGDKhK4dGGwA@@r`oC91De4#oU#eZoy4MTY*r)GlT)KWw^r3U`Q;Lm@#fQqnXiY z;b2@asNwJ&g2uEFYlGcOfaUnTVqZ{xXl4c+u_CsEmV(~6`AjPTc?g{g;zJN{=Ku>9 zkw~I6#F$XG0xCd=@FI#02Odj=@(XRIZLqbdNeK_bQz`6={6H;mKFR}i4opBYnL+}@ z6E4FwMo1Z_Tmsc9goBmDT7d5uCa^eo3Hyk>AxOz!qe>lO`hw5!GBVy;Dib&JSy3DvRn&5E)2pK_m+$iQtnYzSuF~E#vR)z$h zcsLA?sbQKjK^MgciwI63V?zxtY#L#Au^S8&j8@?1;$#51fwurLqK;@;0&2v%i2}mD zOkWUIz(Z#q!ZpyA@{SB49!NtN4k#zg7s|R*f>>xcK(S043VFGVa>Tg%=l~)YC|<+D zqN9lDE7L7RiG2KgrUh^$@l%D1m}Np;i4JpdZ;0MmKpxZ(bz>J8iIB-C(7$+4z&9)> zfh|Tgk}hHmFf_0aW&%f;PzXv8283#Y$7qj(wSdvkDH#X}eIRbR(9m&XnRCOCB*Zb8 zV<4m>$}3~Kl{f$}R;B|4Ju_8`=7G0SL*hFSc*oyjzA{6v0KP#u83r5@kRNLy6U1l) zlrdNltx8B!EEcY(KnKG9c*J;_1c#Xj5a1z^e1h9JGEB-Pz`hi>g;*%T6hb`sWVr3j zwdSZ1qzDub&}U8~llUnkz~fU?xD64ZEJ{UWlqePkmmow$=!K- zj0y)k5Mu+f5)ndk&=GpbGy_Ws7;5;2@(xOb=`DO4rpCao+(r(V@V0Xzgc+fJ4?W3b z1=@xgA5;xKqYGTZ7-J;Rutak(%|_^BH>M-v27m`W=936<0uCWJv#p|}LS_&ogo&4z!X`|f z*al%aLJBf_iGVZhhBy(;CqAoi7pMaOA+snEvD}RL9$*O-p+8+54Q5UZ)4(+la% zxupM8M7Xar;}qz2I(_55Kljn#K0dfl4DM3}_i4iWG~u_oCLG7()jlT8UN>uYmlh26 zVYu(#eH6Hl0wWaAuP09p1!s#m%!Flr8my`KM&g<*=y;EDJh~BsRI!h^UZLhw{ zi{!kJJejxG$&MHOHLmwN3rnjn%PZQet}ZPtbn;?;@;Yz*x3iKL*?W_B2;Hu_#LL)( z0#;w{@+z}>;d<4r?&+m|XYKlXC-m#~lVx}x`gkK^chBf0T zV|}PXEfcYnwX$fIIJR~Zt7>|^`E@cZBufomQ(rFF;h^1J)qA#(=(e+718z)L(QS!! z&i%D}xYR3_^UhkF&DIx1W4^u6?l-vIUp=zjVzxN7RBgC0N!nh1cW1e~n5^R7HG)fH z#Om=}Q$s4B@#=EQAYz&*e@@tCS5*mTGMY-Q>i=ws?&+S8@VMOTsyxZbdyV|Vo8DP&I!*s9ch_o0U9Ha8V{X$LZG-Sa!y)=jx$$1iVnLVZi*;_Y(+g8FYv0tIwYtX9>-%rJCkk2Yt`Ebdr~m9bK+HOi;!1@6a4u>pg#Ak7|Uk2vf$CSp9CUJ z7VgY;JAF*2f$K+~r*;7~*`=jd+;MF#%tm9rI8n@-?#f0x)hR+#J?7=DW83d(J^O$CMC;j~es}BH&-`-hS)c!b!Lxq&#=*00d(Gfkmuzc2^S2wV zXD&ar^~_7=TX+82wXHiBp4+-}e(T`QD{mj%`M@7)J>v_nXg%Zof7E)$D{pE&3g{?dGy?=1~b1!Y({;Y=#Zr_o%p8oN-51#&kKOa2()n6Rk_79&O z+;;8m!EM%i2S@+l39X~=_(bbyaP8pMmp@@}Yw@|ktydpy&3ySUTQgty`@zg7Kir!6 z|9*Bb^CL%EGtY}!GgE$R=CW6`rvK%^gXzC~=V1DmKQfs9v3m#8FZuFd`s9mS)9w2Y zrqh0F`q=Narmy&}!PCCBv-Pwqo;f)3FE7&RtA95*^4_1)>17{m9eLj8TSu-#z*n80jTYJ86 zpta{yXIguH^;3gAul>i?o)^5dwda;?tvwfgt+o3FA8YNt^M=;$ZSNoKzUCvXU0;0U zVAmU8H`w)(A8GA+;T?mW@0%X%eAWF2J74+Bt)0(#>tN^8KQ!36>)%^DAM!V?ofp5S zwezBEAZf=}yupqy{dH@{onLP4@ZUF3Y3uV^t?x@)t(%SyTCEohS~uFQ)|39Ab>r7R z)4K6%uNvI=f}b1Qc*`w=8*g~r;Ks*4rFFxnkGF1k)z=3%JnP>FHyru+;D(DXX(=Gn9C@wc2dl1w&1?3ve%pSSd> z><%ZxL@EEAN}<2c;aRBMb1HQ%&vMSGh4wkM&{ogd$QW7V+yEm%DB+Kd=iCs7IB*j5 zKalj!%y-P4%X!i^uVVv8&YG#5wbzT`0ro%~ z>6>PeO+8VM^u8ozr^iFd>}ljnem58Sy#^U%xQ7J4En%BNN>mg-p-xv9vg6T0YmL$> z+Syu}Y^Eo6s5pI-MWiax_Tlmb~(9?yz{0-;a*wZx+j`v90>LE$B&32o@d6Si%CF`WpStqM7 z=VbTKl68X(Sj&E{TPv?J^b=v;4Ur*gTFLyvHkIgqKp}H+5cXJP_s5Qxm6Mduzm2}V(|>d z>bRV=dc?Jg6+P}Z1Nf`jK6kp9FW6z3U2<6_SrlE_*!Mc7O&Z1GY-_%a>)d3~D~luv zy5C)7{br{-t8JE4GdYOs^h2^v5_R3IK3Ts7jT6PRK`HW^lG!nC?m&nmMc(b0hv(Tk zy4_98>+a@abE(;>E;Kvrr=0Z7*@dJ%KT1=r2-mJ+sUt=5c5`{5y*SrtF7;~?x(&}b z2s)T+vpw_lvTUAx-2xjp&lWAV#hy#lzQik;-F4b{wg;@&ud|i0H~k!un$328eVVV| zHevD2KF4ZUO@srt;9N?ID#UhevaF}VJDYo+*L1%Xyni-kUXQTn!oA{OVk{x;W?9T_ zM(c{(dM%VPn;itV8KMI=HwaQ@^Zg0Wscq*XtS)P3R&mSr}!MoM3h-HceRTiPUUsXSEtL}S@z^_O;{mml!EPD^9Z}Q z6`Dnv%UwgZigNCc^$9e zEM=T?C}VHBjCfs}ZJRg(>y%l?`P8Av-F(Bwe0tL58%E}Jz4mT4a2{&IP*nAOx^F_SP7x|_G1)7SEA!9`(*WA-w zJ!19HHCdw}Laobu(->D)%h)mzwee?HMe1P1ZC&=)%z#lR)Q>S7C0Qew{npNcd1Y^@ z)4$T(B_H@X35Q+R&-BkVN^G_{;`VH=1LDAJw!~(iu@cbvMl|xF(FU9qiI9v*u9@?# zqAJ=XwDvb?jC7gJDP$?*ZPK{vGMh85y3FQmjV`nK{%qDD%X73%W8XuzJJ^&pA1}*eoxy#fEO?K~$?Q z%m|H_+|2llm)y+g=#ow~Hk)s4U2^lStxKMJYcZLdkXhYRyXxt=m)uNyMMq$6n|7Zs zXl~qYNHOL#iK(1pNq|q&JEvz#N%x#fI_F&S+$iLjy~SjyH`nPK)9q}ISBu2SI#P7! zJNBt~`)#UvDUPQ`44kHap>+g2vT z&>uh^zrupbi9F0~UC}UkU(!6#Io_^6b4(`n9o51-(OzJ+^ZS!^G&I$R7 zG4s4;ui#B9d0e+x>h#)dFm#%g*z(2M9-o|DSx>m~aoKIu*H~F-J>EK|9;>!=mROO+ zbiKR=ce-v=b+3O$UgvDwot#LdMR`G97I0;!Cwc~qrNoibe2aOp!Aq7jI`1;oEngbG zWjQSfrS#>?%SAtHZZUgH^YpFk;^FEd^;0Km1sV@)t+UX5`Ic^xkLA@1Ifs`N$@G#< z-4WVzeAtY-s#V$1Csn_vZ`yOfjO&d06Ux5w4*<#*Vl+W|>mE=Xf*PONG0n(#z%c?H3c5Br& zCT&+;V0;TuvxkZve;7wr}{!MtAv)? zyc;)bD*o56L-i=b*T|6;`TVthX+(XKTJy6OH>qwYcrpq)P{EhTk!R$Z0hAoeX*E(S zS?KjgDt^NfsV7_|kTlg(0YR z)`j#cc^p|${*<1X$ycy@OMD}Xw?-h1;!dLFaGQL{T=Z&M0+y zjezfl>tEqkQ%0v(M`IXhwL*wjXeK%(3o0fq!5R~nWOe4`B}Q-Z66?EGUs{z*lTq|? z)f2@ZYP^#!A3s-Lr{_&@2*AtcCNH|9(D?Q?!8_h?U%02im$Z3RMyYIwwult-^>{N~ zUSu8Yq@t2lmb9tj^C6cs)_RS8Dbu4O)Hh|-)MRHES|u4Qt5T{US-58j7Fv*xpXaHJ zkJ4nq^W;-<($AJmc>@ZY-5d5-2}PBA@)_Dv)IuR&VK;gGYKgU5-8Q0>FDnZuR)jaj zOh!*W>5g7n=<&$9SoJyfwMuF+D~6>epN~oz?PIP!1aD5|9e7s0JC2mVry{EQBj`hM z6GdB@=oL{#teDH-L-t)w`mv`~9EveD=Xkqur2VSfQ}uvj!n9f%?ax?E5DiLD0WFhH z#KS|Pi>|DOy}Ok3=dP5di{PP*7CR>=%TF@>NUORGwjK>Ny zb7AB)?1}0pBU7z#3%?>)Ub1G~K2V+x58m4P7r$mx&7C2qOi4i3=Yc8bqAx1wvm$bes}znJ zYCx1vHCDCQ);56-@x-Z-E^5YF#*cxoYW~ugB&=GoQ)FYhP{Y}iTcY1b`EHCJLz;mg zSpjWMrOUHYV5HO4@aAKcj4JNBxe1&+k4jPQ70%099wgMSbVViLjjWN)E2Lc!<}9UU zNi`K{8P9puR#(-Kx5g{a4;YcmGv(JKmm-B2qjBmf_N_#eabz$d7F6KD(}fyW#reF@ z%-va&&u+34v$&-CE^-Si*8bzz6qzi>-gdHmyuD51)??3gkrITlwvw+_FOZAVsz0_Tg{n+w;sWd z%FTU6XaA8}K7`sspL_+%_pmq>BpQ0lShll}K*RH+OCaYWSidm%9K!!YR zD{kV>&J|lwi|iQFDSq>zX2leWqpB)!wFIIFU!JA!?pf{$az9j@#6}J&qug5TJ8vGe zmy`;blDEzP;nxzF!o*ka!b-Q+V^13$%qBqig?$B?D@`HbA;qx+8A3x*S@LWxMwJK( zj@vFII@O!+n^QxvMe(u=4(k4FkG0HhW{T8L*MJ6)ML>txz`TCUS=wwVSYf&p*WJQX zQ9JTj=F#Z`TwUSsG1DPqtAa5T9Ad46g=$+<@k7<`ozu!@qrG$O+*H?B_PpTXfn>XJ_~2<@PuitWh~qQS=u2ORMUai)XK1 zIjfcNY^;<&$qUr%Oq7n^zFw8Of)|ab&55*u#6eRypT+o-YW_cAX z#!8GKYOR%dY{kmzsmdp;A33$mYpwGVvsKio!f^n>VYGn0)c&I=5!`3xgzV}d1DW(B z?aVF{W0fe0m?UYaj?D<0u#t->yfG#dOdrvxqZl*EEdtnRD8d!ESAxbHdhekjbSMB8 z9j!WfM5mjhGy5HENOGdnMyt%VS=xi!b%?`JcuKp@JUocvpx3v>Cq_Bpz%El_^R7N(Dh~L^zx>ktE_~`-* z%NV9P_K#rz6jV{{vsigyL$+17w%5@(`1u&ODwBXP;0H-SWWJrCON1TNfPolj1!1g0 zrV(Jb)58-n2k83YHgDoVPCks!8YC(|q};GMHJvF&O=&!UxB`?P8h18O>izqg*S zOvxB6FDj5yVsd0F+$I>X^kK71q%ZQ1}8v7OPC5l^M&y9RP8(9 zU7TsNLa|AMs#goyq^@)F7&n^PZ2QJ`em!3nBva09NDs(H3FE-JQj!z|#o<7a6D;(bZki ztWTgw)4Dx7>Vin0MxBmj<%=qDkp0+3?k2Oy8A|oYuIW8ygpS}|J@#Vu8AwbK=$)As z%~A5aWwurokD%ywJA}za@G%|pmAI&}ViHiwHzC&%3A&Akxz=GO$TE&AsF@0eonH@+ zj5Fa%|28E;;iL%d?sfzm9Gp60dNn8N2p4STokSZ)9QLAaw%q5 zYXpS>603(?B6dF>t3^x0x zm&7hHWsjK)nP~do5pzt*-G_H)NhE^-}D3u|V@$nwzh@+&{X-?>FK~*v0iAw#W zqlO#ONC?TcPc^ef-cDv0QJC$lfzt1ZYdDOriomGuNn}C^pnxLj5pRAoU328%u-y!X znmg#3m^UYy#6|#Ds3l&iVm1g>h}zas=A_H+B=fYoR?_;N`+Ccgx#ew3ZDxSvZSxWI zBQMJ|4g-9M&2O{#@)+o8uD>uZW}}iYWs%3aE&zH+ikdxie`(*Uwrw8)wIWyOZE31f z+23?~14p-aD3dHh=rGllZ>Q>EBbAhS73j&?qe(~D8f9J$)9Sp+TsMa1TJ{Q-i3FhX zaAaj9YVkpND3HCq#^XF&oN0Z4P5K~AsH!!Gc4FF#+5EBu(1-1;iK+NxRR_*Sbye?5 zMc=5yM34%J)y$f;$S`uXWx}AcJFJ37wX;*lqa>sRxDbb7qz3uSWh~r^B-5Qr!AvNI zno=upS%&DT=8TeLz-+3r@!4SdPn-##^E86WHbX1`09>#5(JNGvp4T;uEER!5!>O>5kpZ+3aa)mX zO|QAm0?U1voY&!MiQ6>!Fy7hr?SF{ z=Yo=}L0T0p67E-#MbU$l(v@F*tWt|II6iXnIulX;a<(C_%?3V%p&oaqTjn}rE_~uEm6DBHc8d|SdYna zA--ZO0utOx)KWs)sYoNkA)u-zJ0L*?0EW(-_`NuA2))v|bIF2oqfZe*$l4N}rPh^M zs;U~L8fpnsONG?81(g5A18YQH$*zmWVX7J$W+0TsiZ!T8i;vPrl*$Rq$V{n*NHQNb z3^Ua8V8c*=0&HQE`H+rD;1dlV@P%c^#mNk${mjJ6j6fX;A#61ag;dK6%-JFLh(`G4 zhes&Q3P^Zlshx|8r5UvuWpT{t**){pT|vO3@~in>HMCl~CM-?P3auWxZCbjUu%NIn zb6EH$Dl%}g&`~44(u*2X)9)kEF_T!BqgEHxD|)57V#MpQtlA*$2SpM-)qy^#y)dsl zf~Sm_4d?Nh`mbocqLplSt7-d+@f{U~sn)1S1?UL9P!4se9D-D)<>?2H7yYqDZI0AN z3Px&FoTHnx!Z;#n!}@jYg1OhKlO<@5R*kxavaXE|z-+4K<)yU>=>lwBFN3GCB=dVB z8A^ugFn$%c-Z>2gYoam_y}U#*6_8U8Q=P9Kwv{_TzD`$GQehLxjT9@UUTZP?Y8r)# zG|DZ|JrTiLmf1EfdqQ9_n=WF$ z)jS~4ZkRA zf?C%>Ud2eKrV?b~YZ zKXQWQoc!gQs%!6o!#i%3NKS2ZWJIo9%F}+QGk>MI%zTKzWyq`%vrM9BV5Mn_C#Z;~ z0-NGtE9O68Gc6&_t=p+rsV*#2nM7qKD$(O8v*B73bdFOIqO3vyGLTjN9*obF8>Uf& zMeKJ?d+EU_&8i`h$P@&Szcuf${-HgqY?p-ZX6p(V48@VM9v@bNEry)C-7E;dbA@2L zuvf)WdTqSwXFI7|n5Pm;I>6|5Wg3a>GOaW6coqH-tzGarCB3Q}g+g|^xiSo+UC|6D zR2X47@fL=Irc7*Iq;dz?2%fnqnpLkNM-*xY1O>1ozguQ0YR$JAMv`Zzo=N9rhHTYY z6}OXCNoOPg$cnLL2_vFTWRV_t?zr5R#XMJG({0}p%d{U9SLq?qmi6tB4~NU`&CdYa ztJbuvXeP8#(}PTfOeRQU7L+qvH%;k0S#ye~FAK^SiJ3zr5!c?MB;c>_QJn>xsf z9Bk93{Wwg@OqV!$vQv*}4iPF*5-QdyEn#v)MnR@ESU8-X=5t3PvGOVi2lR@}Q&&1r z$)|SrsO8X%vm94y3u|Pl=I*4M~b>t||tY&z#Zql2h7@tj0YvJc) zH8pxcgi!ZOWL;TxW^GQ+@s?CYLCB^w_DR`US1d%W*U2y7V2bs#`cq3(HC?E#LKIf5 zs;;LLIj+=A!WwQdC7ReH&WgMp)K$GXa`?c3J=4=DCpsk!8ZCiVWC^s&+p7Qy>$lZF zv=@a*G_5O*ASUP>gU2gIkRE0p~ zEq$42uUG6rkLt}2=$OrsS(`w0rWsFQmc(y4BvBeiVU(n9l-gGAczGG7Vd!R2=0{fU zdUonKZsf`^>E(`MT+{=^X;oU#b1loCe1AupCCetE9p24QB&84)=^6dB+c}Qelku+5 zf{YUnGDBBi959!~(3Qfy~-6SildFR+!@%GdpC&!iMF4{g$jO)@;<~myU3v(SEt|yd!No;!uZf9+qgg@l{IHDSonfMm6AY%n% zuPi2)0DK+4Ur2~r4rK?Az_!fB4JJzyqymZ74k;mSr_6WKf9=*Y6hn7#gOPKHa4~v3~nW?Mn(1{{nmDRnkHI4#ZDlRX5 zBht!J#On3fjmog!xOsW8*d~h=SWO~RU*ke7U5@J>!%5-fjZ#v0aglG1lR3g|o0gL>K7jEx3KSz1Vzn z`n0Tt?G-217^z4eI8(3hs`x|Gbj6&h0EKX|jv=XBBSw_RF_^t&j08|uX@HwSG7G28 zTax}6q014mhhj;j=!nF~vMFGg4%f5fM15SUCncuUth*Mm3iT;mOmvx7E>t}e?UNUJ zs?`%RN5S%-dPHXS98i`8^Dir+C?}{CZ+6`+=>dqNn@?RO1F^JlM?b%lvmk?kzq%?s8J-Y7F#soWms8im|(2-BF0{z zs|p;7&Dd_rW)jRc+`#N^uE4Kpv!0aasl^ax1%y^AqS^Ac>2~diOC)H>OS%sN9W|9E z+D3bJt&%8Ss8S1)Bz9ru$7F@XsQ<`-@Wq&IJYt*N;;0nI%>I2h9X*1ML1~Hlt65dk zA8S+xP!u2f*8uB$S*cntP8HhBsF;BQN>YWa$Qr>eQ)(pfQN?XMJ$!(Ay1bPq?N-Bu zZH28w|0)XeZdQ#0pB`Iz54rBTS{6Mt{A)Br8-9Q)%u&m^vWK;< z)=Z>g4QmwFC|YY2agxvqO7v^buCj{^tE_bb$mr!A^)RlcKI67_SrIYb#U(x~U}{XE ziDZc;s0#`c65Z@=r!qa!qs^h3K~y|jO)F}ArGmWm^7mSqO_|MR)7+~5Zh?UGZTyx1 znJP>V=~O>eq(PP#$SpOSE3as%s9(-30M0YD5T8QyMi&$7NvbAm)dktZsdQDML=u0N z0j^dGQMQVR3zgM01WQmm=9P832(FIsz?CKu_>pt1gy1aVXd(vGtX@8C+$|FtYu7;@ z{ccaa4oXCS*xdEowz4Atlo@ZfY!yVoG0~}p!EEa_r1h(LGK3<%63HBsD9&qEtr=m( z{th*RR+VHR`)ztEK@pA?=oeggD=%48+Yv|zTbKw!;1yM`52ztk6URuRVjY=|R_k{4 z^n+$1naJ9ub!o*13#VCL2s4WBDZq!x^lR%?AK<1+s1+%fW!8euv2sJE8)#{5isZJ$ z|EnQC$2;S_Ss>sp_OV)psb)Gm87~ddOdax+kF_q!%esgV09bEDpeER0Lmgg556b>1 zUHN~Hu=1%e6ak!bRP}w9M58kseQa0_nR*Ch3W!D@j+8o(hZ~=NiEV2 z(oWJY(r(fo(q7U&(oLlOq?<{%kPeUzk`9p$la7#{Mw%wgkZvU%CEZ4PI_Y-O9i(TF z?j${v^eob|NykWckrGl$%1Ak>AeE$9(j2Kxx|?*IG*4O}Es{ENZ(C*4(WSH&m}#N^nB92q!*CBm-Ir?e<6Jz>HA4PK>Dww7m?`eD+KkX}jpQPQhOKSp{r={2MuC%u;R6QrLc{S@hSq@O1J4C!Y{ zuP42M^hVNuBfW|AX421*exCFe(pyPyBfXvU4$?1>-bs2F>D{FFkbaT$OQiRb-bean z(yx%-Px@8T2S~q08jwCn`gPKWNWVe)P11jge-Bpj`+WNH?Vc35FXQiJqaR{dS2y%$ zwAASDRfR9$%7r88B7U!xF6R3EHkd9U-?vM;l(tAxw5*PobG%}mbbqd|l^($L?;t&p z^dJ(fG^Xnx!ui8Ua(sAod;~{Ha_u{-<0Gr%qc}>EdylS;kExE2NNs`B`j!&$PS60WXs^gP5N|L-+SH~xFlqA=lQXQwNyy;dv(0FI$l>Dudj|baIBN`D(`a{AXjEUV z^AlQ88%pusIy7sDW5i>G1PRNI2wc=B#NBusth%FLz*;%&6EYZ{5%THQCre9eS#ouX z%hk?gCo8@Zt!l~&37W{$gcTU#;Tdi&4k}J(eWiPPsoxnZ+dHAxtyMXg!8+bZmrE9{ zS67Nt#HnQS6a5HQ8ZXVUilRE5BQQ(X)iUNfi+X2Rk42U1_z7HHmPb^l_@BHTBT>_8 zpOxzR0s8l!`Q5~ISZiIMGvCA@)=$#|Kh^~Sz1%m|@vwG2%qvM%;2zIeFc=L!gq18cO$_mc&WJy>- zd;bT;0&I?0<4y?JB!ix(St z=Lp@dMK51*71PK83IQ?OC|p82-{XW;>nP`NGhL#?o@ig5>H>r38%WJv(+E+%wil z6vSzm)fu}umzTY<3v5Ls>(F{e{XQG%$o81{pdduo+ zGd_Lm9_G-oud*|dG4fmAtk!TF8SnNcz2o{K-_OjB8|rU$VR2!p4`Ug<>PKFyS0$F! zw7^(LSTeu7NG0k})q)i;di<$R7di|QBiLK6epNS=iB~mOOw4ZrvEYQ^on~_K`1tdb z)*rhhyMW8f&PM%1SFaYMGfHE5Q3$M>VyOXCqETnN*Tgm$ypv6PSjF9M%L1RGS@sr; zQ@s(a$IRIHxifL@PMmua=l;Zbpw5T7)=)F4w6%U0Wt+aD{|>Wpm5H})%$-%gux0X! zG@3K7jw?3;Z|wJEB@`vc%2ghY;8sO?E00i{d2A!}U*D3=J=FQItip)a*nK8@nS)%k z*ShGhbuk*dsQalOJ$%eqj+LvGUHS%hu~-|(q0QL_GGgR5l1nxtRhDlfncE8+%7snZ zNWRKgZXoN>aBd{;+U9d3CABf#K+Z8syOI2u*bQVGTHOug)wXye87m9Dv8>8qZy>9f z@eO3FZTbeXDucg)e9GW&Am0cA*huaXG_axU0uVNqQK5y6WmO1b16eD0v5}krjtyk1 z(a1)!DvYv$j3a1egSj=7*+^y$ZZ?opL7ole(?Dn=Sp^?$B%i`d8_B3p)CMw+z^M)7 zuCUeyaw_Pxk$e>#+elWubYmkq6=d5;Mxfk=vQ_AABYB4aZ)2H3F&oHObxME%xue!t0lbXHVaIIDnhjZkW;UMAD?0pL+S=HCZ13UeTleq1BriNRB&?AvT;J<0Rl%V~k3|*Ndpw4f6!@Zz zS-^ddnSa^T$u!NzLcq-h_CG7G2fp#XU1nrU?T&Hk4AXw6qTpEIvGb1XeJ0QruWfd5 znULq2|3+i~@_X`MeeG<=$vXa{&ZX^>&z|hhedqU4V3Gnd2UaJ!Cp;u`VD+3=J(nf- z>bWF2$~=-BWiCmMGH)cuwdRUse&V4dnIn?WBXct{FC%j@ z(jU1l^D=dkxf%HB-EeoNUp@l*YtJjz^-pXRt`Z!vqzE&TF4)yPi9!Kk|+c|oy`?}Hk>U^X99<8swf3~BH z*?RX!+bi>Ebv~I(TPt0#V`dkh((5zbLM&94^6|>4vFE^E6Qe>PO1)!Lu)*cB3Nmgr zu{Vvt+gdNQGuilL=8l=$wrs86c#@ZnP3#cgNKu;c|wJ9o=~m#V*QnjEKboH%6}$3w36ofwCZ1{F+a*{@gA7pNp1b!a-S?s57nPqY4hDm8>h3^Lr8@*a1R6cTe zX8-N*U;%W~D`(l}V#xGtUQzQl3!lc>zT(?XdN*RRInJMC=olW(?KlseA}nBoGRaFP zh?BU?V>W)X{V>UL%Zoj=c^IZa9LGNIu?L=8@*_&~G7Gb?@N(CU;6X+_ZF4E05CiLYX*> z(PmK|Igal{R_a<=l;nO;M4p{wap3r=6S)z49IdC`zJ)wvd$}LSPLNxcTiBkLWmt$L zcGAEP;~+!_2iT5`?PAVLW3tjNvM4Wor^rH!kh>QZUXfaHS~@nS%=X!pC^;{UDN_W= z_3bni{)m%2%Y57N?9z*(NHzj+)7*+P?Du(~jE`2%ts)9DY#{bKi*w({wnXfZpQe@% zg;3Sy`4MeYtmxSw@G%yAAs}~B=-|5nX4(tvGAyFf&8+jI^iV2HZhEDkBqiFEAj4+cju!-}lc#=eXMhSPI6uRbIH?nZ8B^cR%Q9fbD4{7i zL~*@{)?}qucuCCX#Lk1B2~u!W=#@$8MQIo$wgt>8LeYa|iL&vMFi6AX{4}PtV&5wL zLbeGA?FmOOFKc~x_OzG zmg9tF=qIUNy59M*P1r~)wgM+e3O^2F8{To*Iv(hkMHa9N(zw9Bvp8bkLU6?>X+!J*s$#%{m$*5upY5{Sjh9*H zXPCm+V(Sl^$OD4pLLfT@^CbangVtf+FB%KuoFCi7-uNYCaL{^1=45f=^K2Ku7r8bb zgYB1j5@+H0;Ta+_g-0AA>H1EY;b$fc5aBW6d2tq>pT-cB%Nz^ff)OZlls|zka4>9? z6ufwyfF|H->-+?ZqA;{Ubaonh#2r$%z>OnTKrgbhrE@ zM*F8kvO*l~koZjaf7p8qpgNj$T^M%@?(V_e-66QUYjA?QySqz(Ai-UNYY6V{!JXi6 z*VHdf3bWSKeHJA@|Rl>3`m@{$INz{l6WH zF*X9+9%1JIoB`MY&B|$N!U6bWGBxMmHZx%d#AnO^H$_bWU#tIjQrXxT@OzcR9MHa| zW=2eaTL!Fv3l2^eKraBi?F4YkiJ8TegUR&I3qmzj33@KT%jvBCwjlf8!eNTQg@FEb z!~ig<`QMZPO!_c42d=aXSg-~#7X-K%H{gSn9pLpbe}*CG{$r&Fz@%wF>uKu>F%b&LWlk9)Oq4_}$u4vO#lu7xCG$gKSI@@ zfags?0r7rNKr9~=5U&RX#9BeM05Al=3IJyS0KA|f0K@>020$(Vr2td|&bfQkLT!wF#G{}&PxH#J@`HU0I>VFIW52x(3k(V0q3>=H{hHX;0BzJ0t)~zAD9BUfGH5apSgzq z`#!J^5WswF008~=Z}VkXpqzhH=eG<}!0|up|JDo0@mJk|@`3vOmiwFIPyWB^ z{8w(EUcYq&@&oPuM?AlM@vrzG0Cgc00ngS0QlP#--rsirsndVz04NLeB?AB$e=qx| zE+;*if5wCLNBw`~=l|kYfLszld7!L+RQ6B($N*)4+;9NA2Y?L#3IKrm0`(&X zfCvDf4M4u%wj%)cf!sj*f7|eS?K0wajZ9@szX9oai$DcAF0iXY! z45?oa=!5B=HK=m9+c<-7#wCqO%J0bl}v8G!%OvKRrJ zH~{=<^KZWZ)4%!`6_EGu`Ur5m{2pJwxqv*tvHYhTpsj!U7Fg%6@_vtB;IV(!CxHI> zljpA-z;iyZ-~6*O!2Sjtlfbt4Q{O*z1%7w@JG+5n_MgcB@&nuMUmXXYqy9V&9LGRg z{yI*9=SbkW?YFMLe)d z|5x?@onL|D2WZEiGX5MlKz{(w|9{E^_GtzHfc@vMb$^dbdcZMYAN-eGfaAaA0(pS8 z|E~XMz5mYlF3?WY{{=qaIQsK<4DdI^f7%Gxhxj`n0Y4Cdzo~)i=|I1|JvjhUlow7< zO>IEG-+DqQ00SWbUfhC^wS>`ar_P?g>49J)u0a^HJbZ%pFYH8Cg7WH@(}c?H4~L%R zZJ}SkF0|yp!-Z_XuYif9_ zIdAbDP1*%V*fYffzU4v+X}T88aEOklL6!~WduNypm(L2`6_RpE~zI=uU&7Z-? zKdJtl%u9+%aSin}Q^T?mF;a3!R$H|y`wF8yTvNW^esZ-n3U5Gr!N(Q8o$P?)u~pbG z$H+tXakTFjcE*vhz}yL5rO2HKQ$(qvM(v{L;50*{ke9Tg-O90hrJqhBdeXB-)mnK0 zHf)A-mr~UQjtZs1+rR~89ZcT&5lnzi_PDl-7Xup>NE%F$9Tn%PC6Bq(y8KmK7K>^q z>(>QLolPTXe~J9ZNo2l=7bK;vDp*{&D0kdh2b9tkM!vCF=aCd-g)lj_wu}jA(?Fqy zmRYJVW++5FK6m7!N7M1AAiF=Of(`vg{fDnMq^?vdmEs`9&p$u~q{C7t_UILS#}0|Z z+|DZ$hT6r8$c*`#y3F$G#Xy^y7 zxzcbHo+E+Gp;+5a3?s)6^pTq84@awXl=h!QBh+g()#fAK3UZQC!4j4XmXTN*Yp9!+ zw+~=~p?lAN9!05hF*mZ$IL;TXhcFS^949OeVzpDJ9Ve$yf%Blmw zJwM-9nQ7f<)}LizwwQiODU=Cpg0nYG9p4*CgW@3u&CNafL43G~WgG9)iDpm7k85=s zK^~P4A-1i)9rac(3;_=j#K=3dg@S^T*vHjb;`#KU;)s_+-4)JV+0$Gzo`};-gzx>q z14=tODR0*muhCW1aah5!A?a)-Cf9aX`1G$4Sy0sMI!gGUu9)nfW24(T)&$Cmv3Qj> zl^4=}Rq*z83?sXQeVAO&NgLV4R>FyMzAG?F_NXSQcU`_9l<`by%Ml{*ys*`~M~}C> z<<5x|okN*k>yIES`@+GosuRXE;0v3dK;LiVb>Y*0Kd%@Z7*v9@M7C42@{xWm7}WE+ z{#IHVMCA+#Wr$v>@tq+pE#A!#J7b+wLeW}nPLZ-{9ec*STj%)nTya@AkkFt7QrPxF;RrQ{ zllboJmXMg-qf-JyEG#)uM4;OI= ziMRJSw;P62KW{(>RfFCZO(aCSzwPeTqUBo>hd-GeD{YwL=rPX1-Vj9L?2XhZ$J2Z3b}CaRq9%w({j5&HeS{LuLWgLzOq&-y?zmikvv(b^ z+1xwwkoLN$(I7YVInEm1@X~zx>`Ws3Tq5*^h3a|YKx`lLut5QO;`)8Y>Vi8-aNY=; zN8k<~g?l!7Nft&qf@LPo47DY+^RGQ0Y_6iA2Bax+U(ro3A>P2?`Ni_mt!)*aFLHIh zCfnuXWn6jJXrQn$9lQf$sKYLY#1gUuIB-u2V822&R2^F_jVt&G0#mpek_9o47>}E! z$IW+m1O`+d)|K~evQlyd&M-)j<$ubw;txh;xxMFz!>Wu+HukR?+&|vqD)C1_gb=_S zUa+7sfsN>;V2B+`D!TMX3B?y1t$~$at#LRXeuNTQ*ie_mK<0(m>+F8UhT7L%b3z~S zuQZ0UDeY6}Bz%!4n1+(1Z&9u4OP&9T-A)QeIgl8~K^GlN;}2;;>VIPrPnu10y*`|^ z^8p$5m&b}+9oM8pX}}oO1J>jN*--PUD@D~1UHs_F=bE7>0^x(O{62oVvdZXE8SMFp zq(_w7jbcZk7%+_jIIcAYe*RSkXIV5%*;<}Z?0_j-mssY?GhgNzTO!SHudvw1+2BlDYiyqp#Wkhn zy2khnn!{Wj7)G*S^jxwRc|*Y+;zlJ+Ux+#$hcPt&o^eSLxQz48rx}ZSp?3BJCh+# z;GKy1%q-op136CQ<^B8tM&{REl&?ELcRdCQHhRzWn%KX$&DEY zeu|Tqnor*isL6>h!M{Yg3TwcE3HX!`HB`u3lb-Tj7x3EYl^RbaIhc8yzCDRl6UG|z zgc-fJ;8T`gR=~Q5#s4t%+8T zt&#Ex68crpefu@ympJT%Y&VI4J#{{j@A_v#cvX@aNHD8H^zkn*!@WTcDXv?RA72iZ z-6XN{$ClYZDoI`SpK02TB8DG#&Tj&Ieyx8TATfS9hrK^^5Wqd%n=`%+BH-RO=K;d-ULC7(>#EBWB6H?n4|u)B*~bT@o&I ziK&EJb8LnAjE&* z9Ep-W*5%v~Ep8CTgXGNRw+<7Cg55xCmy|1@Mjz+y{h(rUD%~zW;O(27>8Zp$UxH)U zTbTy+Q>15_fgU3|dy9NZ@5!kG$!fD%nin@l;r6uFHA#n@%;BlY(cU%Dw&&gH=0~8_ zqUifPN{0b+rJuAD&+R2Aq?HAu)EZ5%<^Q=7*M_Jw7AshqqaYr%6dyLH$i9n3F5&ib z?x-Kb!4-dc2grG%%Xo6;fZQ*tG>+hj&IMUIwHc2QNW2;N+HUH^+{RG{om;p z_#dW*P8VgWAW0+9<>^=t+fUC6xEIQUy0NvSjK$Nd&V4_BN4RiaW~9BG;~3D7(csnf z{@IrTM`|z>94i!46hiemk>LvIC3C^a0%5RsvcWogUlk=7|FcvVy;(K*nq3qTdAAo< zrz|214-{bVY266w_Fn$v3N0&DQcg%+r!t2dW$D#8H(LpJw zR)|r)h$)xa=1A!F30uVxOh@+87V5koZ##4}6Ui+y#=pvbLefKzy1fb8H@Hvhb%HJs zx!Rh=`PVBH>g7$;fgbVP3bm-tj3Yek(pVH8wZWks9kQ|!vto|M-R4O>opL_j0u$V36<7r-bp!e9hZPgF#P zU+WYU_MR)AcwWKUlDqS3HH`hxG^)0-RW{`?$y4f;_-OrpgQ^hfxV2)Z_ z4q{SCk!KpSge@OAoGp;g#Pu$U>xfIUv!Lioh=GTidFHJ0)IZ?cNhxJ%XKl4ypLhhDs6Xgh@9548F19^=|D5aRxmfnm ztLn(yED84fl(Q&moJ5-j+qbE}8V;$I0Vk(O)HPZ%kfY6O`~%sVm#5(VEiGwEtbkGC z;S3)8OcLf+BD52X??-;gqK-4YAw&Fg57HtK{q=@P3S+Pz9cem|Ag$G4Km1bmkNtM z$|G{Mvqi`{6s4m-Cv3L85%lLmjTo69)UKHg@{f`hIo#siEmeE34hc7WH&7zWrrMw{ z``IFc)l&nPYr)HJa*j+}d6E$BYR(lk(Y(_NA^QEY`)2T~)g%>#YeJb_x>eQ~)Voog z;;Nzr?8mh%vu1qAL*jZLKTev@sdKWzqnw6GoktE($8f`uWYBt9VxOL5$H3@Im$@N~ zCO8QqW$koKLOJp+BD+Gx--8^Tw}*n%3H{iB@tZr`OoBKKHdH+{F7SD4$xfcf8}c*< zU5W2m_^?XqH+#d^E#KCN+AVwQ2h z!u3kaB!VXTlD6Ypye#8~Q^$`Z-#L#bq9n?+gil9DKnU_`e^GYCj|2*wD3B17KQ}H~ z3k?$O56QvUlD67Uaj`8MUfF@SqUk@y{mcP7Iz?M&+Z4lj7YULYZW`LntbTUax4V?X zEDE|LI}^;WDMM0_pUW!%@>IJoxP!^!k5+WGv!%@|t0g)ycjNx-Edo_6b=E&agZ#=% zi@plgtct<4@$JW3i5wk&Bz%-g9L)xA5C=Wu0ST0*rIq_5$U!l|_n%Hj6LygYhMpi-s2nB_`al1T>L;Mbrg) ze;YH8aCjr^R3C%0@kZmab2EEqaQ0lGz{Q&AqaLw6JCC{#i@`|@^{Z_KHK6ZdKaAr| z;khIfLl8dfhm6>IMEWqX&G}opdX}XC2Ds8=eP0OyW3x0`p+jN1^Oi(I1YPC6afXe{ z*+wz;h#S{bf%gG(V)qJRE*Bctbh>J6Kc0RiuXr&x*<+Xpg86I}V- zGcP-p@@BYx3K3!6h;^6+24RGQ$j|un>5^1DLl`zyx#u8twqZ(O^;Kmo{UCP<+_(B< zh`rFvyGO-`{7sVkhi~GN;X{yAgLmk-F9+m($)o!_iraJ8(9D48+?#aCPn~$KP=lng z*o@tkJeR{^WDKCCfqL)Tr!_4gpZccwk&N7zzM`jrS56T7jiU}@IeWE!Z3%&1c+*dF zbvcnkJkk^U+3qj~8KW z;iSLZr#iB^X4O&AmC?rr!@~sB#A4pfybbe!svud>k${IV1dE+SbFfogPru}d?_%a0 z_<_|Q6Jx+=R*AV-&LDly8%jqD!zZVXkl0x2OnpVQsu4+gV7?WFO_xixvY-7*W4WV~ zSdcw=tgl&5S`uW8>BJQ4EGr2ylL#h8b)l9M!kd=P_kGgr?89XLvLozsfI9WQNGZYR z`!$&j8=OU;Y6lwCE-ei^agc|19N$vBVtpg#?3!+;4zc=P8@9Xic{=pX%4R=^m1cIj zWowfP&zZSsDw8m~2@=TK0h^m2Wm5^3HQy^!r*H=XD|4HbMPFOf z2Bq{xWkk#!J7N(ABors9H~qT`|HQb_S}%zN6INc&X%n4Pu+Rg#-q1JS{f)%{sdSoK zeLq36syh>Q=ZzE%0$Q3~(lVoxIfe11h6OIFa!+bj-`6>(=!WV+2IL&mnNLBO*WY{x ztYEP{sK)CGl|@}VNhI3A)Y_E+39bpW>AV2#?A0hyx&~d zJ!!D2*1E;*NMx4Mnw1u>K8BVNXOv++lexHVr0N3q1K&2QcCA-)dL&473#N=E8;5N3 z?@H`UhOn|g*#(1k8>fGI$R>rDzQER;uMawksYZQEK;inF`f2vJ>YVak5uWjj!jRMf;6}PDwIUTnR23C zl?xT&y9z(JL>Cx@{Zr4Iy@wka<*1NgR{G6A>jHSPEBG?VC)PCvIE#$OR?H{VOBQ|g z5?Z0%=oP1Xj<>bROyN#5Yju^{;h+1`Bl+8##^+T>%X3CsC91aIGiR0{a|t~GRQ&^` zd|uTI@tmEjnQ-jv{0;wh}c7<;O9f!3U7@Wobb5}$s+Gt>WTwi za!1hgRmT@XIaz1i96d#$q#|sj^tycL@J%>cy*h$c@WxwoC}k9i-LiaT+;+4QV0yO0-!X>VAxom;|{nRJXZgr+}}4x{L9p8mq0ZlhV>~ zLz62!#g-APk7c^+$z5CYjhU@VYd()+ZL<8bS!(0;;wcz4n-M|kpa`i?FnX~yiu`Br zG{LpZaDp94$&bvGyx0bA8f0|}byj-vN9v$gGyD^MqRQtsaMPbXwn8bYH`e~VAF;*H z@FYj)SQD(g%ya5iNBb8UBe_I>25k6RRIBMQ_4XjP5if>3@02KqLY7tS>W>7;xy57N zIi)mgy7gIJWA99xg2$h{j42;MXHtmqRJ`<7HOo%j7l6op{9c-I*|nd#XE@}4cl*(Z z)5OJ79J37)1>@MMYR#13vi|&mnTBAnv2M+XRp_j)kq`3RB|JHEpVSSRM?b|6f3!N@ zF6_#G=Z6hq~@B$7WX0$P*YM- zNNh1tMs!&DtR*#1fj_|G%V3oH<>c`0$QBqW_18g>&fbAr6cd97>2H&=BJx=Hxk7*5 zBW+1jRc5bR;$0luMuSD+FgoRm{6uVm9Espu)#-d{b+7J-m%M?T@|A5`Hf$s~<82y~ zpWB58#e}i3LuUM51`*v8jVt}**YD#uKL$wTf(KFCc3><6*;(b2AWzMQRiNyNWQ{nt z$ImRN9SOYR@GOa%=xO5J-9 zjLG+kkLl*z=#=BTnl>#)G9S4KdD_r5RP9k_!v`#bs85AeU53Kz5>u4$s#1Q*tK?=A zLYqEW(@eob^dP}gUIz=K=c6A+-`SSyZ+q{RF~?mY+3D>C&D_|)$bDENd)Z^xGlY}K ziQrX{ghr}71ihst0vCQS{kd6jJ|0D6S!{C4IWGSVW!va_y-}#(rI{YOeRwPg3tpml zoj=?Yg1p_pSX5C1$p`ZwyGsaSy)vQ5;0g9({b6+y)PnOm>sSSyaqS%%j5Kn=TI>^k z&J#8Jl?RRe)eco0LpA;V!jqGDm--!{GGW%Ioyi&#`-f3&89Kx7wag0W|pb+ z^aifD0#T+txROK>vZI0Z1syw`myNXHIef$^J|hDHdr{4OmsIu(_K#vM?N}#aV&ajh zSCW9{P&I$cJ2C73e7!T&i()3$Z*_^XpoS|ps zXqV{QSoHEqWDy}{3c=8lW_#bcW}-dTY{*f$mh1Tr$Z(Bo*(Ey-1(JkQ6ch}CPB6&r zGYAbCiD*^OPt`-E?CM6fD?fasL%>ZB01{>N^TiOP%H~|=)97!7c%^lN2!INLi@g8Eg-y7R}k}6*P_n#O0}yUlf{pguYEv5yvp!3u%gqUu8DOP))9<`LvZ&Ki^+_m_;S!Hj7bxAfrj ziHuEVt}|^+=u?P~{bU>G`vB2{+BaE2+>&rjNvcQ2Y{mO%Ab2ag(!SdACxvb&zV4m9+wxrJ`eTOt<@VYkAc>aDG z_uRVQi-u9R_>H$6;TXB>woF0)-E-yY3#n|~7E+Wj_-_5@EC$zEIXl}_3(k=HXeWEU z&_pmzydv#JZaA4IWULt@5sG~kmoOT}Jk>|5Jt2kqy^QLJEs5Os%83J5ywXM(g<^B2 z9F-yFr%@P(_GyA8@J-U+^`NdR>9rV1g6c1xD0bzSW)i>Km%D4^4*pbXYd02I80_#> zd=RfzfPRzTuloR-ZM({bn@Sl*>tebI9|vB1%XESv5+xiT)Wc+Rvh=2@lARf8hg_>& zzA-9qJAXz9h=Vp+-bjrkgruV0hEuK?370OE1}gR~-LV~i28WB}mOv5ywN~+QK?5hR z6|7o*@EahsuX&E!D6BX?#<80=DZ{Q8!>_K3x1#%D#13u7TE?zzkJqvorGo5eSJS;O zCT+-sk|G7SUx)9zYFEZm085sq@Nu0j#|$r- z@kGxR45$NA9}S1590nXR~ppjlYH@(9%fh zi%nC#x)7H?P-Iqpp2FZXC{Pp_@Q8u^aH~C*rfaNhn2mlY^Xrplj*>!pj2MP9!}*!h z8tNzrhLMuWimBiA*n~uwC*-?1jvoqU3+V#si4c08TR8S;bTpczvv}KKtcxdo;OCBo z5{XF!>SO9j_@3^qZpySAvMGHlr=}6*8&54EsjBgN&VEEeZg)&*Q@mA+x7%tc^QbfQ zxfm%nKll18w#I~Qh23{*7S#1bZK7`lgyojFIX@3wF8W~yypmcAog|YmTrbyrB0Isu z?l%iuGdw5Dnkgt%&P7bDc%;kB4gLQx>3CR z*UuearG}qOER3ogf=6iHw59>?Ijv>Ei(^JLWfPARQ}jA{XoU<)iO|k*4C+`84(C#G z({DFbf9|`xmNYJ3IY*N=ZU-GK4yIg@0OAWugAU+1U2!WQV$bDG0VHV7383O58Dfj_zzBSB`9fS)##DU3#pD(~n!ebu7 zuZ>|NHd8jF(=OnazMPc<9@rZP%UeZz&~Y45=4!dfqJ6{hXdEc;2+pr#{Mfpiobl7f z>LvX%S7m5~*;Ix_vYUiu3X%(YkwWBTo<0|Y ze2gX9p)G2Y$T-~&6ex5)AXXb>vN!IcV`GxQAsP;|Z-ICU=J>vV_OE z*mt%vc0zW|FEqk(%3v4*UlloVq5ZS7V5dN=QY>|fKc5%O-LIw7Psy>L&Yxu0=4BG# zUC?_gMtdAVEQB<)RMSTDDn4w6RLUCv#HdHFwwl$qC*CY`<7a!AsP^~_ww3+8J8cw) z)U<`Fi*I>|S=Iy!R2r{ZGF_eS&ij7cNcYQ-!wQn4Ly0_Ac*KPvL@kEir&mr%nJiH! z8M^$+6@{y>4D;w4s9n63L&Rfuw-cR=mOr9xp1N<>CBqs5hOD38^}VHzgcEJxqB~NV z_9^u}4ty`}Aghyqk=!R;KL-}g z)Q2rHvGUGb+nv$Rwth@OJd}B6_fnf%N*UW8M4ffX#wj($MYInIYmzcifKqcS#<;u0 zM!H`ZLXqtRfkxvqcGbmB!Yfgd&+tyj1X(A)${iH=uyYBEGNxBO0+Hf?%JtCX>H?-P zR7BC3Q*;jb6v9iJw9tZmzh56dpw_OK=U}IqfQ~ zRTYZjFioib*vm5ymq@;$Y*sCZCd*Rrk+u^SLjBhPIKxy10)_!rjU@!#)APtjA$VUk zY__saFinRfFTB!Tx+Yq6JLn8Igd8YTc$ze>y9?|MDHhRFAM6QjY^=tHN4C|ENT!j! zYpi~H#he9&>l5#@L1bBWi6QSO5#|odtq5xM7d|{UJL5|BCd(0ZJEPI=HP<+azZND- zi{@?&xYK{9FkMwi;tkNjJ}_DR#%E$bmi?Y=iIL!oHsO?3^$-S!M=IY6Nvm^cY~UU z$YP=0^zQDo9}_8=iEXx$8!K_E!%+o1i{s2=yPNT|Q+y?Kpzrz5Vf4<8#-J>elBPH^ zaQ2R#+E<<*9zScxrsB(T&dz3a4E2-U{3cmW{k zxaFzz!}401ii)$6%wLo&GOF)KYNWFxw?2pI^9{AVf-P~yuA5$?lAI!4^>vM-n_(kU zcyN+5T<1TTub_{R;=Mviz^UR8-#fr_N#r9r$HE2yUGM$$rNbcAaXRbk)a~YlW^wJ& z133CTwlN3BV?Kj$uEkwJ+`#e6hjRucSH|0@krDH$??j9@h@;DMTMk8^rNggjx-%Ri zH$NPq@aD9oDz-9!fw4k+N94H?%um;Oz;7d@qr@%Vdh%l&>@kHUDVqD8`-n_deAhbM z*J^X=z06XVsE3Udxt$9v;Um7Q($rCno?+cp|8Ro==2E&$IwjTY{1nROM;eSP2X~eI ze3K)5D6M^=W5TA+_7e{U{6SV_@smjYLs07bv|0#@E`PfY%(SoHg|oA@Cc+T-cpC^` zKix#D(c^PF#y)jcP^tGwj|PBp)bG=Tcpa1#r>bVbRw}mrqG*2EOFnrj%kc|qG|$5r z7AzRF|0Zw%b}ldA<2LQ1VG)ARD<8^U;zS;{2Qx6tS+6)lPd>nN2}ebYVXd=!CUh5S z-q}Q~9nH4r6?3VMFn^0o-DbSKiTS01WtM4CFJNwiHeGLiyATy`q#J3QI%<+E%LXQN z{#|uvoB{(T=~@!Mcj+sX#!7@wh`Rrq>aF)@`NUKuT+7#icjV8=XHiFy3` zOt$Uan1!1ny>}wJ4^GYg?4vvA`(c84V?5l|m?=n0?D(sNhb9uL zV_*57BC0jdg8SO%Lkm=A(3#cGU!0X535tb~S=Rz}+=f132QAd}`Dt@o)?ANig}cnX z_E@)!=f*9@yoM2YwUwqUB$UIcP>yn)Il&K1l7R$3IQafT3yq;ZKL$x~&bSZJBK5Gj zvN&gyM`to~y&K5CP+s!7vl%YOr)H7WOS#1+V$3RV#IF7}RGUu-GF65k{L<=S?S8#e z!qfw*#;>SM3tJNR3s$&^ugvw}nK|ctFadeJJC3I`SpD=)n>{me>G`WBGI&5YK^jTX zAy?+aYJyF9P*!a9m$Km}Tz6zFhI$d)D8#6h@)wTrN*!G}&2pP3k+h;r0=s3cPYW*G z1MT2zS1vrlF+8S3dAsYPUbxoGSr%~toYPVv+O=XiVEgaoK4Cnr1XXlGExK+}^!5`n zx<$A=xmKzfGQdb`ybJnziqmFX=((H?Ior=L)1N3hJ=kSOnk~p3tJvT&D`mU*T;lxL z<@saoz&oh6*>P}dFCT-&L>1D$bZ8r~;C=s1i<+y6_Lt(ub+_diq>6cEq*VV?p5E(? zK;jYlabI-TLCzH2j}YAITiqWc5FzS?{0p9(X|cHTEF&03xeSm7+2398cd}MwtnFW2 zCh5(O<{n;~-Qk<=4jd+_F{HqPk}#$$VJbm&n1ktdV5_{gV7p|WK>n)t!9B-;YMphv zRv)+bW`fv{+u^jTMN*hNd~!3xYcoAt@;x-%9)|#@9WL+Pa#>F>rrhp66lhoCM$$}W zRin)xGXcM!UDg^+M53-G{Nzhh$%m@o1r{HWG$A-RCpwG}$2_{zM(NHVoIwAqX^S9P zFn|84zbbK0#KXqt=^Z2#DgI4OhB@b>i5#3=nR!TR9QGFTY)Nd8zWBoYo9Y_il4NF% zL;I`Xib=}c!ByKtJU!(kLNLk zxlu7B7CRDnG2mYe$I=$0-6~ewOYQi(p}h3*EPJ}Z6x>M@MXG6KEpwqCyU`X9DK|ze zadYgDVXiH`sx6nInm8I0Ue84Ep+Jdo-JJPxI_tY5IS%@pUcrs@G%T zaTW7HoJ0I5e^Y-HB)aJKyhk9qm9jv|8H|Kc&3{9?OKb4-TzGv(c2EnOx`G!TMt7lV zBy`|Z|Drj+q%_m$7>RN@`sgbCZCqnw&^(~%ovVYg8#g&;wi7Hm)XSmea$x{<0{2>D zze3jFclYxP=S!b}0Df8Veci5s9(|hPNpcahxrCV=R(Q*jm-!~+BVj}KcBxz_M~G(j zWe(P79?gt}73^$iu}@Pc+!@|ntZU6&MRq!KxiP5~gz{;_J*UJAFUILu>f2#hkdv$| zCk>RhHda4U~gy9fjRWUXT7JiL)9#mVP zt!+3^s!jtw0EIN@OjoW$NHXJ;M?s)=y zKBcTPJQ<@nxe;l@I?+bF?f7*NqrWW-1_aGq;z%)yEpa793)#PNGLu zoKQ)-Yd?EG&6we!uSAJ+h?#%OLpxPvA;UBTK}AMuf}QN?RueMG2-7j=sASv3KYFFD zS5y$m;GgmG^=aUFc*}arGtdq(d5hw>DYsjNGiBgGoF%FMBQi8)sCw=q6w6Pm<~7_o z(rb`bkIVS6fi*%eGBL8LK^{`hj%T{2C?lNai|D!=LC;!O6*iN(85jP@U&uN0G|%ie z)SoSlQxZt;I@Y`qPiVUr;d&@p%(6FR)s-dplY=R}*XWjJkKtp~l$p`CC zjtR^*<>cYURB|HEzd_$i;C7?dl!uUtF=0yAoLOHBV6$x-aEo{UZDMrs5Hz z(h19|e_s;BDP-{crQbij`pZjvu~qK2|Gw&MJ1(^%JNJu&+u7Yyrps z&5q}iccl>{WH@~HgygjB5|ay+9A^wSVD~nHA-dGIr;&9%WG1mX3+&J9{R0mtg&{$w zXtkjk0}c&mS6g}Q36)EGa~0KKNJCcKGs3E>m?oSC)V!rMQ3Or*p4h=~y5IR&7<#$M zBuVk%hqB*)EOaH(dJnV0?DVZiXlgc$F=Z`g9)c{#(W`N2>nPVBsYl4s`d8bjPs;B4eW!SnYFi_oMuK^Ydxkv zcKNxc;dv@M;*e(h3Wl^=8*dz%J|XN%mzlDHjK3Ta^LLml9;$8>3_Tr}V}8ys?Ti}W z3YE^Kox-r%E|)53GFy74h%of#elJmoQul-Y%?#1|#HHylA_zJ&?xY`dm}67zqjua? zZ=xU^^!v2QWkEhxKdu?GRh@_z7AVU_=YE9I3r4DS=Uh~}&zHd}16Wr5fqgAC58S!Z z({*N-6dOi@376kTALevE;G0cgz#3|Kt~sdLb!wJzb5i0T!eYJ&oOWp~nj!m4mu>Zf zsi6NjxtqfHcA=T45ZxBr&%Yt97B=DX^-X|@x>ix=Ge@C6vAIzteeAPOe8McxMGR(# z?Vv^wOqXyUqbm(FqO{+SIQ>%hXxDGHRNnf~Vlkqpf$5TyPPM~cj5(iIpa@E_jMoTR zt6%D+@L74aU*Jz*iL*m^zdm-9%LSA2D=%E4m+bk|f%Ss>h*wNtk)wWD86OE%_|i92 zt^)pzlHZ#QB|yIeXUQymh!;)I0g0ht1pz~heJFNgd4VZN<^>Ji(q2HU`k}=2u}+)0 z=tD-FZ$rPOe|XED++*QfwwtEzh+d^0&6tc_qW^~+^6UI`RV0GdMaKI!{vJ*@S+*>^ z<>#!Nsn7I=j;zLsZWha5eZ7m%&P%>Pb2v#>TFyGiS$Ebfx1N~r-O&+F{-7v1x9<-i z!wu9V_Mu;|B?F5gi>wJ{R~}H-VRgBJ-ntR4&R&x18tFq(rsw&!*sG?5Fc$ji3Im%# zsO?vZ;n%pyxYxi-7)HsmcT?vpTZ*)4eiT5W{9%q;KN5TRJnb#mXHC5O+2{vXa(~AP zjS8Y1<`pW9>B3W!X)57I+G+npqs3}ZbC(Yc3a>*M{#i`8r~_XKd<*Pzk%?#45th=H zp%D#E!>OP3YGMn}JNvNQ!fQh@NXhtBvoh2;-skR!gv%~2BhjoE7>>s`;BCuw)qPfQ%VSkl4Zn>hETfnszHYOpe0l-W-UyJ6^)fk$1r1!>HW7wfoR6`l>y1k2lr$)lb^ z%Rg?HtBkenW}FM*>qm_!j^zz5j}bIVrfMj0lZW)oTbqvbL?$(`Jb`IcLvYGX`uL;T zv+V$u%)PUCGd9#s)6SD+GjL1J5VsPvtW{uh(?1_dbkpYm^rIs(b3RG{SPgY77@BG~ zl9>l7C(D7Oo6l3?fti8a7(+)Y{}7Y1dU|gniIteTvhl>RNM)|}_=?l5^REfF@g089 zuIbQqMzu==Y!LpA?m&;1(V|i4Q&MEoF+CprDMBp7;0@!w90#j4%A;g zj>LHnMKCJPbDE(lnMKaWK`kbeRPiOOmbt%J!$ivWQ3+^*4f@~t+$)M2d`Y=`C%unv zUp2v#)QKlUMyLMkA+wSQPbWQlY6dhy?Ohm$I4P(Gcvm>Q7Fb+$q7{!RLMOL`lx?TS z&>bwzcTjDLWR|Z#GWkoxhxu%T)(f`0WKJXBx+}+8?A+6HZe`-np|amy-~U_|1BVT6 zkt4gu2C)hgQOwoZ96+=hKo1DL?CPDu@U;FhF1%l(xpYT{%jDAuGYQQv4r=j!A^(1c z>VOv5Y9Mo{WjB-|uBDT`Vi>*$T&yaK=lE@;{ zx%I6FkQao7Y=P!nXT(=}ag}kVu#m}|a%*sRV4qe zsRKFGxJpK8Mw)532uc`lwORG}Ml;6FoEy66?P`c*X_~Ym{{1W$(T2v@Rgw4_rf{^E zPIP>2gQ1MZ9>Hs6;7{KSx>9T?bwjgiljs<{@6lNev2=&kUTfous8FtY7coy1p7aI# zGh^IY+V33{xi4iXa!+A}o(_9iJy<@aqHc-%$XXif;`DM*9~NXAJJW&VL*$)o_nhI! zXi-I?1}SHKlJ8X^n&4v|eq|rj#|!k9R8{6rWX!BLEhW@|i2P(8J0?PKAX!9G%D!J) zfp~scoDUVg<%+*TR9l_eumV{XYoWg|V*ZJWqK*OHwJ7!LsGeP4rWc+~RjACOfh>(j zIjp|9v18Ij#vF6wfaJ&!^Q{hU9Njoo(6PC$o)zzNo3I1PZf5U$i3?n$mYlZus3L{X4IF@%w8A z_K_`AVTI3>h3gh;v&nJ$&3^6oKdbNqaJ1S-#rJ)`A^g4*iTky7Tk7wc*8u z@hdlT8ZEx-WgE>)TM0UL$wArd6pAt{@FAcX6wiyF><>D36b|_euO^P6ACJfFnH_B+ z+z;mRg*O|8ezE{0L1C}{ZQbYV%onlH>!2B76EgKJiwYUtOK+5jQSP3GVK++=k@0%(TG{L*aowuT z4E=y-`?EvLUKWWJeXgDpx{E+??{=kL=ERLMEqM3zizr;{fTLHhPSRz34h5J9#++C; z5EkLI7x~ZY>BdAkpI<`QKP+`EAryj1B8W$UG$I@--uo*PPSZplQ76PPV7^}P!U$`8 zm_AzYm=*%ZKM@&xZXYi=@sFKsFdc4}UoB`#c}aLoNXGd!g3_<}@nR5n~G z^WxI)W9on1KOWTOTzlTV*af~KUxqfIjMhqRc7yUk7IIqO4d-loobQq)k`imjvP`|v zkhL!F3VZdQp`W^!F%I>_(-^v$cjw2X%{>EEI9>EaXxxD&rEmLt@UO8cS*EGMU)#jg zlJT2`ctv8(KB_eG3EGwB7dl(_m3tRputinb6&v8nNQ&S|lF=uutsutU8RZB?z<{=Z zG^~QsmNB(U@jh@x<%)T?#uN}U7sklByL72@$SAs*<+SX6`5yo;K+wOX>MY%dj)2R& z5Ho~!^ZV^s3M^h-)t^7Y?;W1Kxt zjJCijC*=~K(#K>icO1ZCasGN+eJ(%zbAsD}qj#FnH`a|+A) z5+i!95X8uM@t6u3&*N?t3ge1yZJNN^Uvf+37*MJO zGYH5}xr+iyReLlkc_=i$7>x6=?^C&%HDJ!!W}msFKOKJO1+CNvirn>)Rn$?xkseHjv_lgM z6WJt=hg6I(oj_o@bY-wc3G4Y^8g3%%ZnyndZo%4z>{19~aQ8>QxICdHLTcxeg3kA_ zy(^VUl5#|IgIan+3b(`x*#+(8Fr8->Wgml~y7b%~IBpfhj)`d^ZBTkrsH1)!Kw`fJr?x=?#={&0!Ia9gJ zLlM+PCXg>-qM|ptG_URquxq)y(^NfSPf|Uw6up?(br-aNrSV44{X1*g@~6}$7liEa zd<8Gk-~)-W?lY0~8Ww4;t;Vmn;H(4CLo1rC_mQB@?jYHpHA0tM8m&#dJ5xbwHs4vR z_=n-jr-(1_jFNh8D!gNRmJlWlf zwfy3NPcs&3-c+C zP+Rts%*1wehGDwD`dOP>M(Vm0&U%l%Kh&|FWL9`6Y>hcM-B0Ys=+wps6QfH4{gvu> zFJ@@C)hq$leA#~oeEdOjj&zbx79d1Xh}K$tWkmaLAC;&u6*V3mqzbFJGdbpIk{xw4 zJWCn2P_~tJ6PP5QckAoaMI7#x3oEx0H=abr4^hkMF`8;uwpq+PIykzt2eTqVt>5^FE>6_B+VicLhG^nOL|$ zmCAYS>~A3OT&z1&4wI)7XTK?#b$1F8yyO^KX7^xNovK) z-2THI(2rG?g0|an3t42&v6=bP)3U?pL3L?Yk(@VgQk8F4E1?K5zpmSkqF}+qR9aU_7NnK`58NN z#3hHSX!h7-pxZKS?#(RmO>`!AaiE`hS=QrB%Bab z=Q<(KazgcftmIhHw14VYMU2;$y9-HpNX`>2u~!%(<<_TM%=2U$(Pr!VK?*V|q{+Km~r~2bl~V-mz&s@h(u7d81qDpy{7U)2$6D zk8?9(TJXP9V%U}=1Vo*AX-q7rvWiipqD8~YJm~PS1&Dxl1yT)h?ND(XUtWn8(iR;c z=dz|nA!Uy>0PNRJc6_t4yc#VU7?TYYO){@P7N-7wrs5glP|fMZOHlR}NvXfEE?ZSc z8nxuxF=~#QRfvxp$3}yCgplgv5WSjSeY;$oP43P>5qpn5y(|rMv+{XZx<9(p)|W9K z{6V-lVP>&)ho_b4abJ4yN(75Ght7#3u4|36Bz9%n)R_&%L4ZMNftUv#p+jgiVsWu4 zzXb3p3U`^U0vN(Onud9~Ix4#hL0>tqAh-Vutil#26)0+K8~dxD^lIqFGB*jgfW|bB zd_XLdxd*x{wI4u3PJV}ko6(j@H0r4Ttz9(^2W?oWj4P66v&t$nGhP83?z5CxNX`Bl zcv;VJfv>D!+=JcXy4xeO0+H^j>1{8n=s6hHnLv7~|1))28WDg^MoPITU@J$xuMOaC zOVa<-=+lhKA}&D*PfDh?S-D>s@WaL+4oh4A9;}(dNid(s zrCDCrn;YdLC8tb+9k_untH=((G}J@SiH#q3!}~h=>3tUb@2Mr{F8YT zH^R30BX3u8d6}xMt=#nA_BkZ5N5((`%b6&xrThrr@{G^pECVS*fqeC{Z&!g*%)iK& z4Uf^q?&#tBr+J~N>du$YBMFqN(1m2vS~pUzHYQMIwvXv`k#+wXHaUhLXi_aD0$Mn5 zGJl~CXJB4+8L&tQ% zer-hqK&bHQcN4LfQe#Tw)Vim^0k+=dQQ79P^svjBReRG__w<2!5qnu{xO=KO?;PIv z)b0ZSJt&CBqWB(f^=khnK`y8d4GoRZZ?ecP?6K)dru1I-(8)VxJ#E=S;DhQ^ER80< z?*MF&u4OnOZ~lkt0_weZg_u-D*?)Z&MDlOnUfHS-pXWBFOtc-G)+y7lZ7Eu0C^~T9H;$-UWl>*zT~&4|9*cP4(@uED3P`OD4ngiswY>aj8D05JI>r3o!Y zXFD{_Wvk)OCO{PZD;LteJO8}c>OfZ9Z+(Lq7c`QdNDqMa7-i~1P=Iz4-#A7T4H1V$ zPGVh+sh3?E8~UMfJ-BemmeQ!`R5gU=bM+pV_emwyMJ!Rdhu<7mEByBBE^)nvW$&yJ zFpx~H@MESOdtMN;?{KW4)otV>1=)JXveCU)_h5|tn6BX4p4y1O%lHYn&G)NGXEjLT zW&GFbi6CHW-TnP9dtG&_f$mJ8n_Cq<7j)Vx;skDnn>$a=u+?F$k!2pR%1+SIGx4H( zL)!wRem<7zq#hJ%QXPTL@IobsHgek&%5O?xt~-$*eA1*i+6^+rbE#wy`P3UHU(CdM z+-Oq)BQIZozA1qeIAS`9mCai3ht5|sM^*&lY66Y*VhA&n^cJESPZ$_hi`iG#VQ?VW z?K5GCEJ>;0l+qb5w~ta?iJh`jhP}{d2ug)YF2SdWPqom(5D5H&QVxhMMj0AcHgrWS z+NYIv9Usw8jTC)!DUdH8sREFA0ywB6TTWJQ1M`}ZrW|A@I2){}q;ohjMhf}jC( zv?S0Y>so^a3*8!rE@nx}7w-oMw2RX3&!L^6C|6%e%>LAg<4$(_sZjx~W8AGO$kvp# zILH9r5vC?MePsgN{~6$<#Poe;c2s9;WRk5fCBky#g?8VCTJbR=eyNjyH=5%@nPnlt zofn9U;-8U5+pKmCl(pc!m6r>I;d17eIPVNc$?`--Y^3&?@i!*+gw{E(<@c|L@3pKB zl>uU%>G1sVl4XRVkLo6u=o)4L-Sb%(WY9e2Ffjs$wh2kdw8TZM$Ra?;y~HgJdKo}@ zM=Fnk^i{Ka_0c;sF^LW`#SEF4KAF^ws@pP!(|tk5KQ~fgS(mXchpL zWlCz5PKQFMVB{@=X}LMErURowrD}df8~P*{J!^ zfAas-kE;>7&o{`pPS?`5V>FYUQA zowxLgw=x!39=c9}V>P=tXGy9=Y^CTf5+q0#C)5R=$TC-T&S@n&;JIoJE}9vjGsMor zh~-HqDgfBzFPjdWL5ngXKx&8Tl2L(;4i5_euv#m}j|m!94~SvJZd z!h@O{5m$VXKwKozbRApUTJ+g`VSoh_CIog9hJo~}OW9Pbl9ffn?15}#aPE~hYJj63Gk5+Szzltxl z9o`r7^IJGXM-m{l%Y_zy;lX3DkIoaD`>6cl{@XgGRP1` zK(8$uSb6cR-S5%zZgcQ6;+#$(3eEK(E~{gKlNdyJZ^b}<+iQV#*Z94h-euMYoa?xa z?i;Cj)9AA=m!1kQTF~kj+K7L1i?vu-I3=`Z@_3FFDEh)D*ce5~A_n&8DWETRpLm33 ziEqFHVNo!2tI?w~l+hTI6nkHsr2__uA!p+=2%hF&ZG$WfS}|%%Unt04ZjhiQw|N)W z>T$RY^SJEQ@OEM4ph5%{Pg%OUI_O$ADY&Y4SP!%BZZqQ4(8I)t4uJf(Ny0AF;1%iB z5QXP9EL-Eb<@={q&%fxzy{#v~NUpMHQwe39cKYV1g=u#ydHr%q@sg2Ca^RrzxkzB? z6%09i;ySPK0a><8gj8~@~Zq-RAJ$22(JGM-a~9Zub;&d1RqgE8R` z%oK=pz@u3zRL64qJmg-uJQc63;;SEnlLH{>8q`AsplIBEFbRz=u&O(HI1guEsiyv+ zw_!neqDRJ<=$^RyINZt5)|st0o+_Pm1vhWTC?=TBA?W1Y=)Dho z5gUW0F74+@vV@mG>MsJpqr0g}(fZ!UV~%26bb5`zDD<&^rZ=eDNdmA_0n1TAzW6O2 z3M<>A(Sb=21wFk!MK+Zxg3iz#vH3)^@%2)d!UV^BorF|!rj6qu%(X$GBcHrlPy~jM z`tu0-V*@)x$IE9%5t#|yg9$f9=pfr$5F9yH8h)?#rRD6XzOWFH9t-Qn7({gBIQi3# zJ^pxjV2h{+=h-Tq|A9@2b5Dx>sbW(5Q*;j~kFyu5EH`!28LeUgbQmBIMih98R_nDm z;*J9ZESQNUv)DwCJq~KFCPB_m%y`47uPvH}y`1HZE4^DYzuh(Hv z0lo7Fl(ozl88b9tFWfQ{?P`#v4WS}8)OR-BRO*+*;v5ZFrj}Pb6!6I}>K`JGbjx9D zFzZUiT{>MpVN#K$dVdPM;9jiokKwXt84($Mz$9P1XKQ?47XOQreqvojShK8kD||$U zQn)Z;;s0k4_Y+=HM`+EuMmgQXTe)-|uZOV?=IEmkShKukN>|~=x_7+_@`TU8m+u!8&9mKli`?gQCSai=fa6@DoU@-<7T>nI_?0h;qf|Yf> zbvCI#j5`s-iG+abr`tX1U z;zEJo+XPHXUjRc@W7gB7+JJ|{?#Q7$HxwuFzYGnRQ(Tdy+ zJqiH@Zf&;w;eXT>Z`khMnhuB5%S)$_mCGS(v zU#g1$E|<>P_iM0aAFqBf;_);Vf{j)mD!RA>56vfoIM z40(`1(!gjc4MLQGV?r2gN0@x2W5a=R?%z}P@~nD>I;5>DnlY_l1XVFsM>4oXvUVel zz|Z<)s^(JZ^+vQ$!yyCv?LMOgSCo}EgzYlr`U{YFVm%SFt7JJ~MB?RuA3PVGA1?N1 zXuuZJ%!CcqvQEvdGdxfkHfoF+0ct7wLPRXFjSAZ%26@C0I@wc@v}os(Xlv&Y+BZ+e zhf1@mn(re;!*2leAOUGOrVmv9DtBH-7hziR`C<2X)8&%VTsuflCFG27Grx&l#|9@# z8p(ju`-CrdB}Ubp(y%kzXg#e2zbo-G!wq924pSIXl@D3hDkNR=z6kLmuliMzOv+iwA|r+Z2}b$b#A&N46n=of-7stv50mu zWXfx3MBSpD*0`OqtSI52&ZJ3P+`>;O8LMgJ%YMjU6%%Uzc`EP@f&^ZbWSL|xhVK&9 ziz`^19rQBQhl(c86Z&P&^)H6U^!NKf+@yS`J5lRJl9(QXzpVSXW5-zjv85P7Kgrd0Q;99vX3rULM{Bt!T9^AYE1gC2ajt-o}G zSd#Fo{_TAd?#9L;k)6#kRSNl*o-$?ztxPgfjG-l04f{v{UuQy7GdOx><(~U#J&Q~W zT-$-m@08E^?Vaf>VFd?|LF_XSJ`-uXj3WmO((9PsxW>8s#K7h>D{nL1gjG4rUqjZ9 z)O7X@28YfVWReOS)@uusWH9<^c`&$*4ZoZtGd>eCvBA1u^^#&&ke(bb4ss80aJ^O; z(Wwld#*y}naXE8^`-f?8h!pz-#8Zu@PKxIR!m0H{ZW?H(MFdt@SHUe|xcmdG4FM_m z-(tm$NLrlgsxnnes%eW*qdt9{DaJ$ofXI7#Y`Mwe_0oSGm)bAwyIE|=+{ZA~*t{z; zi-wSryx|AfCt%dn!W*8Qgx^G!Vx%qTe4392O@Ur+vGb)agmQjo&HGq0A^QwG<9(CpQ=F&3v0l)c%+0!SvBR%ZcD$ zHSI$mcwQ>YrdoE$BCCakL?s>IMNLcfz$z^^jBMItaujzSHqqJYbqRC!anp0mmVh#5 zo|LsqecB_)1Sjbi1tqrGNpW3=g`}oA{$79w@U<{VGu<1OOxyvlH9lanOpq?!xTcmWhf+_YTh|~}! z<0fjW#Sb%}r;sg9QBOxcz?IpwQ=JATxDD%59Po8CpLgvU|jzo5t6@{P6 zjdoY+g@No{ne;y*aT}XGOIbiI9Hbwa%357ytN8-)z3qm$Z*-p9f=5U^1n%n|a(FS< z!lCFOWC}sk#OY_(vy_u7&BVrUi0oCnUV*#)z1-r=oVs`l$Qw*BcCP;ep;umb@34YM z99`}PCypJpbL@Z!1p{6ih$y&$=q@=rgwKu2aOu7vfoqn8G*@+vaDchNn)&OTLfT2P zSaEd9sk3bPd)KAlyW8c(*?CtR?Yv?RajeqU*9o3H9e2x`XY_nq$%&pFsukC5840Y- z7_X+HyWtF{A9;q7z@T*e?Rm4cd=D>`+>0ylw6MZE`tBx6XIG3HgKFwgyavinpRZEV zXrgzQU_{TNxR~-q;W7+;H5p!^gOOXU?V+%iC9j&Cp`%Sn9&xSkslneZwFl{AbBzDW zPSj_Bgirk|4jS;b;v^dIG#8g5hf)~5ka zSoZS-Q2B-}xR2GzM9a{A6kPle-`atJBn7JtXmG0R_wp zMvI=0M|nE=F~eKAH{_RLRC4m9coe9aQ{AsnuKs|PRIm?il5_;|@E8f|z^ZTNJwiYC z%Cfu!W_i8p90F0_k+>0wx8H;^7jqMuIGs%-he(~q_t zS8J<05oXylGLikTOqvv73!!A1bG)6Je2ub}Wj>KyYs?jZ&=gWQ2=2`fLQ_J9rSjD? zWp8}SqYCt;-;V&YRi4R%@?Wq|(_}8ufX-8gM!87_jAyym`=>%He6y!|-|Jpa{f zBPCAg;2cSWn*MRz8flm?Oz}7;El1t$0uP!HE^Bxb?*~p=XL)WTicq2rV8LTaDuqW; zYzM`A|4vGwL$EVvE$rsh<=xFmDaJQRLp7_CcTGsMRlAjcaCxVmjwEPm>cht(xW7nIZoux$>zLQ z<_TDUKQ)I*zv#?O4CHmU=l~2Zepi|#UezP~>9OvW0d%||<739H<4?u1T@qUjbhaeU zWH3FIeQ(}#bd%VnteEU$q9?6Fx$5KXDDEq~ML&HPgl?^Vf$9S8$;L{hTJRGN=25h( zJL7&!qCmVmhHm{C&f)QS6!*1S&Ze+?x-i!ep6=n4OyDnLu6sC8PtC!Aqqy9?9umir zH&q9n;jJSW#sAtkUvmRrep_OoH8HjjqR#!O77GzW(iJsr1l2`(;=o(ZzB5;9YcLl| zK7jb7{C91`m$`RoaqS|!;j2kIzO=|WLw`K(aXo~R`Q`xV|$eTf-L1q&|}%Zw{B@=O*0flw_z;9nWJj! znKip<$qaW9nk$ag{684VYQ8!jJSQ|02S8RY_)g>9fY*o+Vlv@^4Kt@6&3_v5&*Nyw)=?aner1G^?j0+I^xQ2GLiD zgh&{pc_)iu8USwiWdS}~`69rzZAqZ?09jhJJ)CS?QDE=hF@r9*&(8X8nYBs0rfcyl zgtZQtxifgPfEaWSKCb6D*^p5{Adv7M!;+;KMzfyeM;goI$4x7r3%D9ZSx3yxAP2O! zgIkae_MU)3^t;ERTL{ZP6o@5_ZX#xzU3+w$8K>z;akP1k6buqv=PSsq#q%DdOrJYz z!f0e2`h%J>t%HUFJ$#b6ZwTQ*0dv;D?E?ACmU>M8`xU*D*SWjOx-#jqKUIc@*;*N^ zdvN4lXU`%uyr7#(f1o~f#||bFQRn`EF^^|$BmINQu=q3o@9qlK)?ZXFJe7~>Tlq;j zv(`1P?_BJiS*@8ad0HR^c?}!;)z$b=R_vmE?Da_?Tebs!FSXoj2m)H+0}O%K(r8Rp zi_mNv=V#8y3TT;Ss9@<8t&*DInP9d4`nI8)PQRFO{DE zrQU9G5bZ zLbXX|nwHCMCi}ciXwrGqpW^#yx1CyloMFubnzRkqZ21$*izcQZCXZ{HW5YBG-2Y)c z?WY2M%B|u%D=%08R=78hP}>YzG^P`vNBT zTzD%Zs^1p8`zubqdmYQkFx{e$BHlL-G4L z(j?wFz}gYHvycdM+Tl!xl&cvQV+KZvk2M?kegRL*izO`fk+V;Af517XdoZolI$~>{ zhpO10!+Os<2{>G%=efo-vF`9}p~>!J_^&MU*AMs`G}r_JrfJK%`e!C!6uBUm;m`zc zyyxCzowla3NOx(#a=ql%Lxceu&7I$&hnfYU^xoZ!hdaGRvTNyG6v~Mw^cQFE?tCP#?n1WECGnya@^}v-ok?_gciv~A zVN=Zt(v33C#6d-IR(n={w~wl-yJ;7~q6GqexI7=T5+sHo7#2ts?(A4@T;^TZ4P)PH zpbOUgrVvdO>^Kl;6AnJmoZ;`|Yje@Y4VXj?c1gnP?JFBq{IW@cXwPgevkW|Lt+iu) zfCt{{rP>)YQgWrd-J%vmH*2;HDm04hucn4j`YW<8JekY#Hdr!lS4Uv1WWt|$Cc-?2T|6R=fCii16 z=3hq{B#WCrGqn2$b%G(#>sl1oC!0WnIsg4;gL^7xz$h5s%=O?L3q@~-T_FE6`oU|@ z-boNygVlx)m){s&+ea<26YGH5jqdoE4#cUUVnmuEm)S9;T^x<2z_> zgWCNOzUoh@D~pIFg1?ZVZI58}Iwys1saHYFSd4v7OyVY8?{LvA5~m=u`t`M6_37Tq z){rw*(@BRQw8_%6+bq1VEqSDF>boLY)X&xbZ<(~+Mk)xCePjaLgD1!0=$i8A8}GUNO|Z#_ z6JS|{5!;^26LYuEa$4XC@j?Ya#r2aP&AVyw5t2{AivX-WBgAb{&d@rz9nFyenzjwZ zhA`|Lr;;Wds(0qP&r@QPA^CBM86J)R7+6E7zR}VU=s{S95g!(SC@i9me27TJ-&cdQ zR0SJ0Y3Na?&W-_^D-(~hW%v$aogpJ1&Tw>H6;&SgEPh3Kxh2M8P9}RgY62E}k@K{C z83R7zRJcCr!lbH+lPZXC9*xQZP_}d2eT?^%K3wsPQof_jtK+N`1dFhG| zCU^?xHNJ78#A}LAvi{>;$Q#cqzC;-6nODVWrc_^153FzNp3F#DQR9Dlhfgw^jR1%f6SG%EXNPcdZ%O26- zP@Bj#M7!yHuZonX9iWz_C$zjsUTiTarM09(b_#zLW>d1a)6}Jy{;VV|HOvv?>EvOrz|wNPGK2 zn|o(qR@wTWhG`^{22zeUL28D|Oe!5Pwa@z#>+=qYz}-2v(a1SqT2tZgIxL6Z9f!QMV2?0sT z^ag>(z`)CdAUR#B7uS_QwCgvvt_-+pM?y5Y@1Dk_qHdKF?? z)G`ugnJF)J0}8>>Ze6^|@+H*+El-i=ThzvV9x1(j++I)dU=zukS5DBu+7idLe zqHOYO_RjHp4XdTnHR2CL2hSgZ+#5nR$p+#Ec)`W$ zJ?OOG71LwT{W{MKsE@e@cauTnc_ig88tq8Z@X@Vn`2^d!$d|Nnw{x0_YNw&?H zWQo#1I#+oO!J>pxzEHkF%LXhuNZyF4NfW5r4CxXWKfVjhTOD|Nz^h*>tSq zF6S5&peeo)dOb^aBsG1>*CG&2O_mcIj1Cc$5jQEj{pW%S5)g$F@>SN_C@Ru6VzO5E zWRh5om0tdLq+>X97b0~S=ldBi)|+Puv>m~OT-CB zMRW}W`NIt6I#iVvN}!*P&}EoAs0&C~4OURfc~Ws1Us-=vCA@bO=K%r$i7$<$oqESt z3B?|e$$0j^f07d3lN5)9cpH$ikga06qppocwYFv^^|>P~Yc^31>2E^1l7lr$HaH&iq272R-v*Gj34|auuFDkq=n`-Hz`DlK_eAyJph`=jMJSgzF6T(^A>PPd;Y%|kT<33E~|0{#h}zFY?pXx1d0Au_dZ zg=#_^6v8XpU?f-zOMTH z2P>%0#8fR@02Ta?SOTOb+K4{7Dt)kR< z>=|UVZYGBqx&vA?JDH)k#gxh@ZwZY2hRTdbWJz$VUfj~wzsagn#HA@7ucD$LMxl|% z;$n%-GFq@KbxqbvVuw0L%U<0lT7cd&NXWQ=Dvu?F|-nySp4*&$TVeyDnrtI z(X@5m)g@S(-_8wr+{7*aCTBLl;>Rt&FGedu6Xd-vso}iQ`6*Zlfdh)NDKi7{hD+lKAG`M zHRQ0QdZIhH#VP>brb`LD?076pn<(6Z#*=u4iPK0u!%Kr zMRH7c!@m8w1MuT{S8+i4QjdPtO=u~7XX3)-^&szYVJcUxq@0azgT+%4%{PpLK?kNS z!a+pGLhf;4a5434Zyb<3wWIo?KA`H0=YH7>G>QQaL)3= zSH2*3il|Wc#$EKzHgL!y`4j1#7jF+ z*Qog$Q^y;5)<1~)?njX)Q0@c6he(Wc^um{$EJ6xr&Sd;o?0$>nsV`}qk6!dxW{&|N zy``BxQZ_AABVx+fJZJYTTvjDpW*g>1U}E{h(YqhORwoW(V_3a!iexLI;Oql^_Met&Ln!dKOxB`C9N&0+vSyIO^iegLUSS-LArX-HAf4R_# z&23>>bqeOGokF-g7uf1H$|9+w_STL1s0>Ss*JY(%aE#{P-AXpYbQrHWSYYX%FVmef zY+$uFFR4euJF>MjLR7W938qj}t<*E5-sbh!lS8&NkK$TEQXr7uo=}3dwlGI*%Bg#V z275)=shwQsnU@WiFi}oTTONc94f9ga>i-7r&^g=(7B+((%;oq4Qgcbprl*0?RZ&=zI0USxttYE;4D79VWyZMO&b+~FLW^Peiq<6iz zuQDHRhX`lZ;`1G{Po&%KO>_1Q55rvcAy>Kn(jOd+ik0*L#`Lz3i$+pTCJR zonu2G?43Y4;r?*QzQhpl`fuBkS7md5h}?%^Qx_EMQ9i`n+{>F280BAtQE% zUWGk^ba8SOK=MCmi4DM1{r-i#&en-1z0QVE>vQEdmYocc_W}uA4{k9CndpNfI^HfN zQI~HZftD!FoJA2N7Ex(B`LL?kz76OHIqi*xegU#tAZ_y^^A^TV)C0!>a*%*`PBSGi zs@*g?#?YmN8grSP*Tu`Ln9+5g1*0I^6;!zjzW|k4+B{D@7;fO`2u|tFIvfIU12pUC z)=5fFM=!!*(mymr;r~>n71he>;y*H-)jHeLT}A<5P>QSdb=ao<@siq4UfeWk(clII zVUE*Uv4YwFHQS0z=z#p?HGti5usca{!%t7oTgwB2UwK8KUG$gLfsX!^QEvu$X+FX| zhm_0)RAK|$o6T zT><`7ny!^}x+{pro;uJsp{^ub-UI-9`Y7h_&+pU61C_zEF@2 z=0_u{;a_BKFew1SFq>db*0}!lKKf~<3W+iG2PEvpTOS(WER)rf1{D)Qh@;YQ^{`9n z{HX4POv^kxFurLT7azRQ{xMMaAMNV69}NrS%O7h!5_z6lypRKr<8sXlLlPb=VGECa zGqvS{(}u49xwT}zL~pk}@W#k?L=PMi9)Oh#>6)3X%vE$N17=kK16)I3wC?uX+L_}3 z7k7ql(3KE4!$vOwn6b&A>IAxjX;?3WW1}ftV2Q@UU`2jI{uDX;5a?G!$`%(pEgqMq zpC|`l99nj0HR(@;G!y{G{S*v(JQmAzZd|qi>xYbSQaACUX{KHDr`4=pWO+y2sh4cx zUAW)H1UxGPS=pejG*6bnj?RdqJ@mG*&1C|MV19ag&L}EReOB@N+``vk{5YPk{kXlV z5ucZ{y4PTbWr-Pgv%ofx^$lB+DD8d z>gaxauyAJqV7HtQwH{*i_q|aIF(HPv8892jNFw=G~;!t}TZ zVu(=~C)d$Lzbz)8o6=im)4vFT)L4_;UB&jCU<1b1Ud4`O5lAEW9BiZF3XjL|Yr0~F zVYS1C{~`ay29k|=!K7`8EvT$p$7?r%ks3Et!cE?J{w9*j$fJdb_DN_^DUJl?@;vO> z+9c!^zWIJh$(E4^7Vw+np^OPP@3;Bc4_i`!JBfUk2tPWy3JJl4kTch$7)!4d0qIf% zJ9^*n0Qp9+nS=*&C1j|$pBpfth-5~;{*cN6j`bYee_)Dql&)t@9Tp_As=7y!1HdBo z1hvo_DTfVdbl#`HpmD*=n9Ru8s<0j5`~djq7KqnMwx6ALkkr^M0RQHWA~~(kHmvir zrsqx|WlSq-^CZ*J(6k>afjc&4&{si<&8C^d2+VLyQv{%};~TWUl1cbVwA8 z;Js|WGC1)v3b?m+?-X0hn7C(!UiLCpuxPQ9O<;AB7|KKO`y$mzU1J}ViFp+^#^0fd zP!6KzYQGS%CY%t?v-07bB6FJ!)X$v+$K-*g9`(slWSa{uIr!piCEh`L4RClXqepjJ z35eh=0_d6;!_cw=p$`S`si4NERs`HA?2cjcS`BtSb0Fmx-A*%kd2zy_1yW7N;bIwu zDZ8TLcZ>k6H#mr?y!xb_x;!BS7Ys$8erLwks4wU`HI&^Z*1$ZXEBJOeGQL~OS6hJ; zfXXLVX*wL#c>W7c02q)A-6V!Npa_m8^z*q#mLF9tvJ~XDo6UaDbM1A72{J%!dItah zhzCWrQGKdCb>w&K`gLr1oN>5kHg$tcD5_#J(m&ee*n|R?{Ex`_GYm5jHOAmn{k76M zze5FE+|>>WG43;njo%?rV3f16*?t-U1WgiTyS@U2W%q)v2#=o>R++VK2x=ji@>L67 zkM5!bV9@$ux-4tHMsC@?PCUkVVJ(2Ll2Q6)v%J~ zFc70rKdkUtOE!~v_;2w5taSnjQOLf*-x52S@&p7b_~78wov2T&T1`A7EgVKnnmyOd zI)7kh<%&-Aw6l_$q3)oGkYt#QaQq>ss`;*Jhmi|+lW;D+R(^v@evG@5z9O-psq>8r zvlpThB~D090S|9HE!Q4+*EL}F``LRgH=wo|h9f6w9~ev!gJ)4w?tt-XUuoT(ySZ1s z@aMw@(2T*_C4}=S(h*`RSH{nf2VZDa`NG|&mVv%52;w75C=$o@j!^(gK()W+-^^6m zL+pPhWAer%suc;n45(A8R4V>#8%63yn|Rw+U5DMt?Ib$%3~PmF*N5t&E)Pje-lqex|-h3I#L@S&Uudn>S6{c#gXaPC5zs zyqUcAMz35V-j>lisemS!u;6Brr6mr5m~wG%pe7B#9aV>P-ou0`x;;GoTvo=NLj^Q^>g-BpSh4F^y2!}Tt*L6 z9^KP(z9IB-b4^aLxn{?1FcY4$2$JK@V-x}5ctI325{$^49!}s{!mepET7CpG1=R3O zm5?@S)ulZ(qGio_`#T8(Z=>%;3U1BdPE`drK;o8+4C^5QNZ(h-_pmHpx2BH=Rx5yH zc@R0*y0S=TtTIy+=+}}3?6BnB55fX{@}-?~eDCLV;@HYYpkK>+k9)$e25lbVW!YG_#d;PR8}%;XiE!wWNPO{8>ph9kEQc z-IP9i<$XB@r(|;86qn;^X#0sE?$CDHzyBG5emxH~-yj*f7d*KS0{R^s&sc4q`OY=V z89O;C=oU*JI&NoLA>efI+!hlJ2fN4EKeQI?T@=n9__;llrEWD4ffUL&<|=-?T@F0T zU?2-M;|kDQEV-XZ$sa#b=_S|(kZ{-uj6xtk{SG}MM!aR}Z?=mhej_YVwTssI?&Q;` z3!}&+pi8mOU?+iL@+KUB4WRq<-XA%=x$%MO zLNNgqX`$~LMQEQ)jad?TevXwVa2SMdFXnC7hAAF5N@<_e5*e*g#Ee>mS9J85B0b_1 zUPdue5^w(`Fs+E922)dkJQvfkV`#OPJW5%7B;gcTrg}5;6=>{(oRa;o)_cP$k%25_ zO4RROu*97-apif3f{`Ad-9$KTW{FkgmoR36+)G9t6K|G>P&7G@CxbWFN+oJI+Pe~c z7{+~NpW*XI!>#^c_BeYxi*w zr3N95eiOqsVhuJcX6|u{^p_^jkbFBjcO?h@duW_@%OD3~zt(AQWVo5T&~6E+zHOFs z4=lQUN{h-V?t`W5rb#W5Lv^~wJ{<{RqD!WsB8tPN{r}Zaylj08vjS+vf!bcnCuGh9 z$rfok86dAh8PK*!)6Y0CFa3lZfb~(L*7O3CVtg&x>LqX(2GUak=2dz$6d4wA_Prmb z!Z#S*UCpuK(f-i?yrQ8I zQ$wS-(m$dqjYn9jzl?h(O7|%zXTqhNOrygs6r~)7KNrV_yl1sd$4dB!f|P@p0fN;s z_KgP>YF;&5Zng^bBBx#1tLHmoJ&y7muN<7R#9MbG@cH=a3yO3P2i&TX;uM?h5LtW*W z13&50R{vyr0V#F4ciuK^XbmIx$p8&((16uh@nEK@`Q{k4EpJ-{W)^o^kVUsUE&FX+ic$%9Gk+!}DkulqIrWG~ROKZ4*g$Mg79$%%jy_WAS^Zt92R&|SG@LiLfOOhrl;JUs=_=C51z;!3$1G8Od66O1?_J>)w`L_EEi2F6rc z^>vRI`_7~1obD^)JoA8g3wKeXUEqE3xmy~r-}AvK`17R}R~l4N`m8e#5^Ub}s4a2L z8v={U3TVZskvMbd=bHoAVMLk?0qcImbcZi6l`lYbmWJ>06cE3+bZ=3dY*9z2hJcW~ z5_eD# z3v@1Y81U!>6NwT4R?WTY-(Pc-Zl4cMh8d_Qkyg?dBE`bjKvKnwDbZNAAdt^aXi?NB z_z!l{fH#m#Yo2$(l`L%9ijdYP|I;s}l7gournVRQ&3Jk=pWbt;gI)P?6cNvE5B~iJrlRP=@eyKR6s5N?y@#-E!Go}xvmh4YP5K+cg~86F+pYfSZim94`NFwi>4u1vYx(ONHXD! z5oM&@X!o_9`9g7|{2#`^)|&hr`f|@r_{h;|c3*a77RL22Q=)}yH^1nP`Wuu_co`Xi z`oHs_5UTdYsO}YBvC$GTeVppR8@SS}I$OH8ta#{vy?U0tb>vq&uQ|@`^&S6dumkwa zP>;wL3`+OV!ZpPhi6b>+1W6IY27~rZKeGH0o{%pD5+8skh@wm5(m&^U z+UTuNDGC&SdK~R{l(-Jafy^CK@sqQERLk+TECy9!7L?tntEB8cP!SgK3XSW(pzC;H zhT^j^sQ*x3xf76!D$d4!4||u65J-mYBV2{x%p<1NnMwqU+1*Jt5jORigE_4TYX+1D zrEJG2rkwgCI?$<#6?0I=xmQB}x}|C0uC604V)_dLsq%JD?bQu2i;oyi6AGk+Ij2Gs zq&CI@CPO15p!Jx)!n-a8>l+r(*szOv9N4!cDXCvMS)Pg8+HWCr{G#@K^sl30n!|T- z?=zrbRW}6Xj{>n5J&o=`F^dp|R!Rp8ZEV=g3uxrQw%w>G`^w-9xouoqb~0+}!G4n1 zaHN(B=e*qo6G_HUOoBNM?K44GI^lOUxuF;ki)Q0Y7ij~owW0)0;PFdcpT+)^3Q!=&bkVbsBxxBJc|2kbPLCU#W+&VJU z)Lc%3`W2Q{6jyMZ5n{dF#-HM_lO?9jd}uQn+pcB!lbf=X8RUM+l^Nj{G7LSFx?Dzl zk3kT%ln&KhjlTD?AA_)5{P|*T=l+XTUJT6I-*B59P`r_(g|=^{j(r82KCVgQ2uU%UMN8{ZRx2x2e<8%SXz zKQQZ1;XR~@DmKy9m;QzPaeNkm(A?J^cB~DF2pGF`ph1l< zoIrp4Jj}_=GYnSk_!#9gLKRbHP((PvCO%-R2jp55YII4LotYrZ}suFJE5c zYwFe^XN=*|CH6^~3FoO_Ba@2^XWQ|antlAYtpi5i6_Ab;&%_N#ovMo&gZK!c7FZ*7GBTI{_W+M3HNZY>mQv^7xOPh6W+ z3{pCvbo=>gZ{R)~>vKnly80C2H19~L8D8jDjqtNNJ{9{^{+}MNRM<-36WxOKhCDX} zH-|KPa`umW4+Dub@mIS_wcpZZcevV3mxx1s@w=or^X@IYQIp3a*FV3PTK;vd3oKt6 z_OF-OLad2$^&Y(rWemtE5iZUp;Eel>rQIeJl%{<~hoqOF1Y2nLUkY#I%?SQLOwHWu zZjIM+@Ninn@xc{20g;Ab_d$lEX|~GJuArEkNo^(A56aHb4f>E&Nwl%okE&)59`hd^ z#nSoc-BMX@Ed#sMKjg9MX7oAQ7p?!mo@?7d>c2ntyyW)40;Do+W}}rP6kzJedsaMrBfW+j`v9+|`*6e6B3^y;$`^6)#3eWApn=&d30x zeiY@5>6v*z6b2pgfhP`%A|?PNoSDyIRDqDn8h3tlXfQZ3#C2ne6cB~Tx*0o8pV%H; z62-B0miZJ|6(e=x*PYPovu}L@k^oO<>2AzEhzHUKg|-(Eg^bkx77bf5A7xe&bw(O- zGGtOsU5_&q-YS#Qh0cSoN{?XbeMOBKleL(aSU+2#Xe}&J(xyM%W~`IIO^HaWeohyt zp&$-%Bvrp*cocEO@78voS5Wspr`kHBBz20;ooMR%rC1H3U#=#|mnI`M=7}Mg1V#6uT;g z%AZ9L&CN0eE$-)FFa$KvvD--GO)U=^iY|-XOtV; z1o%*D;fbB|`X`$XID0mU*L1DLJ3AX?nr^sbSQAd)qOIxGTa&Xu-v$Z3`9cc2-fcWM zrF??Y6&K_~H|dJqu5P>)uiDQ11Lu+5!bmY~g5O-F-IeO^cqd``cdMwoZ*GR_=Q%es z{E-jl->etQd`7Z`UB4qWroirknCXe*-YTHxg>E;G^3z^X1zditGEL>yJIhRS+yFI4 zvTdr9GcKy0oVpHhM@T1)>p*MZUz1ms{vHz*`n^|{qZBwSD=tYZL|!kuC=cIPM(p}8&1+-Hez)vm*2h`wV5Zam6N3F5m;{h#Ciq<2EY#! zosB!YJ@tvmGB}{M_+(%ogETQ^a0ubE7+zv7ur-%=8b))naKqBGIV5imW30!FE?P)o za>fG_cEge$GA=OXNq0-)E={_6noZF^ML$1(kI79rKry!@+$I9%I&GJ#$T+kS!>;-E zEhSjQd|4S&f0SKjzRaKTj;IVODuVVMcC%?V2*6~c)xhng!Bt6QedOa|Yf+j^)WqNn zFE43u6~(74VHl>Uw0xhIy7n(d_yp=^norY{LZR&+pgy&RQ-}zZ|ERaFD{|{D>KvKn zk>Jq(2r{V&`o%{FB@#<+)=+bSVmp*wWZg7 zxQwa;HUoX!A-M@hOK-40Z_qA=4Jk7lq{EWqx!!_-^8HLr>MeSa%VA^jE$m8rEX|fN z{Z9Hyf7jZ9!|kMTN%Ig`5zL)eY#jC)udCcc&<9YkblnXe8@Al{gz)%*%{8z9iK=l< z@v*;pc1h|Nh*TW-kT@?B-oEC!ml<+3ifRkeCJ!^EL;tdhr`%_Xp;GFA;qn^{tPziS z`Vd?>3+F~-`Z&32H|``7tc59_?sK(FQQUFii{d=cO1A{@5A|9X*^QIBL=6 zJE+S#YiE6jB#?@>QlawGq-Z>U$yXP5sW%(i|E1w>Ia~k!3co%(ukh;Y#M00^RRZAt z-ShbSH(#)7j{DZ*swWbvq$B2)D7e!cHaC)p4&KwYqcbfXFXp(xfXzAn`z=9usbf@jJ&~IvvCekbLDVYO1WABw6?FUr6SIB~!{;m^*fbJT*^y$O^Fr6WAW`loj z0;np<^H1%xkdKNc|M!KuSBsapv^5(9Y3sd2E~-zfwZ2>>G_5vlD*XJ60! zZ}V9-(79`g&^viJC~W#zAWO#Al#`7C&`hG z^eQ07s~g6*Th4g08JUjfu$YLOOFoK))OtQj0Ni2^=6{cZ@bq7^bAWmFQg>eLjI4rnUM5Ae zzu8^&kzi?e<`lF@8khhl0?FfNe8sE5e(m+azQAG&U;wxShEmt z4;r!LxQ12cp%zlg2IB4REE$=Wo4vZt?ruU|mx@!=)|7oPZ7Dq*HIff0#E3ppQV?k?Lr|V%1{oBs(|wq#I4-~Prf^- zNhABOa!woV@Uh-O)UqaJsJR(Llt~om9hc_V9 z;XPa{#UOVwZwcWl!e027QCxV)gR@;U5T#{T)pL12bZHyPQ&K6|c=TfNb@N}4BOq!q z>}Uq|?QVDcbJ1`s`V+{fKEb4IT{>*fAj)N7*p>{^+bI$G{_NX8?8U(Ci?V&muJLGP zfW{e+apCxjk{Y?KDz5)0GsecnHF0mmjUo{9FQL*un34M+efeE|O(Uc{FqaMril z?6Z0rwC<)fuPt9RHtTdQOzh-^B1V|HVr^cnt`Cqj9)?m%m z5U+p@B@~053o&#sf~^@+Z=K#jXKfF+i5N(0gGZ#q(JeS^8?$FtPK2zXq$jBWhEPDJ zKPjSK_WIEwmUxJIaT@hy$rJ%jFk`{!oq**Y zdfv>MUJu>}!~P>~=$PX>*=<{>CAu`Drrlh3V?r+dr%3o*)`vcz)wp=WZN@l-K;wLt z;P0q?wy&I7ggWKZpDQ9jh&lw}$zl!sBIY1OZS4U-n5$Y=KSmIq%VbR-cGFIBb8W&K zZRGeeSG9%R1>m{CPyFOccAu)tVe}a8&l(1R%kI!`;m>r$K7rJVZ&$w(OHwMr6aw(q zlz(*E)L-+|fH?{N6E`-I+YYDHEfo7Ka7|~YjZj;n3+@s~V_;U#|7~_mdNz}g*%-fX z&-YEMFZM&49VWi}t^x#L=mt|+l5GM_KjucV$vl1`WiH|iztZ>r3Vv4`4?Pvk zTQ64fHJjFbBT@ws)<|RjAfrCQYFhpo&L2tIjE%*S?0{3IXK{>JEhUNx zFy-62{}zwnjiE_oAdl`QqugfErE;NZl|`UnuSj*SZxNIj^xQgD!)3{qZ&0~-2~oA& zw{F(E){KW=jLLIgEQ6f zSU9`q06nHLYiH*_Eo1D0^`*((P_a<^2u{Z{DP-kfG13u`Gf!gaLA!!44#?k-t9$5J8FID4BN=0G^ryLj3**RAd23d-6m&3O zK09ii&rS0#PQi2bRGV%LS4lqc^1RGaaNs1x{d}p6px9BNJA8Fhg}WzY?1XEcJwxsq ziE%r$fBtRVOni#>=;lErKu%D1(Y0oFISo?NRo%mf4@Cv=SNV#)Dr*Yfq_pVPp27E9 zk}2K37PrzuWdfYL<18BZ94-ykqbo8h2YX#e7NkX@xUI3kPfXVgf8|atmgsz>4)4l! zncKTsA{;YgzCJ|EiN4T+45<|XDalcj6Vo+TaVy5A^+)~L=DU88Z?Qd=2Ui#dG9 ztO|CMp<-vik%1up&Fr?$GN@?Q0}bJSVwi0)u*VwYYWYhb{}DZ^a1H1(VS!Ri58%<+ ztIznLuk3E(n{)8((Q43UeeI_}L+LTie>8m0BF!Q=@q@pumIrejqyS8waVMUKF7Sl( zH&W>Gk$}nqLLi#ygX1@+xfPdADEgiacjGY< z($aa{M#(#U!;{Ke+GLQqyIOT3+0s ziMwa(9-ZKdWtSPZdKsceC(qe_7`gtLd>?tMK?!p$nIf>0R`D!wW3? z=v=Hel})LQ>a@pRRGb8p-pYZ=cX5(ep`AsNvOdML=)An7)66sMpcZp^=u{02NWaV= zD=SeLOL%Qbzx;$^O3mV!CXj)79u^W7a(oIXwuX%KKmj1T#?1Mvf50Yo(@yQUj~+~P z;rWs7n$%?G#`3sim!?Z;3|P+*p$d8gq@Z?uO&)|up1=r&IJ zC9d}{Jj)Qk(r%cV-oG>f$R~al+0z0dU5i+{a!4%zu3E_C>}l<0IGWN2g6>vXyai{( z8j7CZt?r6SJAg>kGnby0m~m;{C6x_@y5SjS*8Q;Zf`?DBY4|?NfRF!K@kegDzj@yG z|GBa$aSH1pCxO$k5~MR~CmW*sU&*+t7L#MAt)J1y7-)+JdcHBXVuu!2i;6aRY%%9A zwa!&5=BZlXR-*#br(jS;KI`-mfdt1bOM6PLfXndTc3zt4w=QsD(V`Y;n}wiLo%-m7 zY^3Il0dH+7VP8f%?0g&5AcbjPd=&sFut!^PgLc?hill*ix#TB}}l-aokao5ejWyH^*+vF1tnYxZ7+4Y80piZE0 z-=O{iL9aW+_AXJGHNt@>A0=lK7`3NfMb3@Ap9&echL{}_km%fW9a%`m)B0N!G09gr z1vcwz@IG9VtnQxyeztIVc-2~G+r#N`{jB!B#B9qU4^MJhGaFdf@+LTy=X8zo6X3Ev zNlX`iK#}nyI?gck8=8^TDZ(c6Wj?p4Z+ClD`VL3AMwx(ny)mB2o^BK86NNfldeD{9 z-HzVSVO@2FP9?c$I>9)pxz>k5hVz81yL4n4kI?Lz5 zl>KYAtWRWn+a|A1bRx`mH~Dl;Fa=ib4-brPHK=%0sk5(X3ctj4LN1n0$3!CcvqMC_ zahc<-njo3Ur{sMwTpak6;u!m#rGjI2TU>Pf z3WlRu;9?hDy#Y?=vHCJ~_1Hw>z6BSW;su+=Eur~K6Rc{oS|xFbS%f~(Rv6N^r030X zHiPTg;uIzLc&o+LE7MD1k>jD#zi>>#V*2#&(R!kya)89~>$2)T_oZ{29EiW=7`0`| z*6pJ+B%|6u7o4r~Zqj9AZfaGZffI*XZ#W=CZ88$)Q^&dS0Ak@rlb)k%yTIn_dG`-Q zW)qzBp(YO)*dTi6t%FLp9FDAPz`v0}_oW8f>+qSEEvf(grjzJkRq=I!BY$1~ zIc~z*_a1dl}aq-v#fzhJ)jPh8eP4h%R*dcqq0#q|_dQj75(%$XsoBB`pU>EH{ zQzwwg)Umm>lxm2>gIUjN_X(u+$qkirfBbiuRPmL6t z>C-Vrd-hsQ4nMCE$laR^PMf{PZTn*Jp59PH39QT?*V9eT8*Fi0uxuN6=3s4C=NIB? zlJ?Gf^XP40D-<4(o$=cLAaw{M9Po{*%mktvPR$?Yo%9f$M%5ok&bwB02{4vbs&=9e7w-lfl=9|(nM`_T}PX;bQ%j0 zOSccb@N(}ZYvj+o++gh<9w2~4ajBH>?bOzB=@#qwR6ElI_QoZ^}DT2WPmiXbyj%qlA|ezqm-U9Ua9HX6J%XV52a2KQS%>sJ7=bZCzA)FfX~3 zL_zsOFyvo*XYXwLgFCuPTGK0X}=T$s6T-i#4R8}O}wg`z+FU>&&Dmi5}qE6zq- zzSpbFz)$ihMo(K6*XonQno4ydRei(AB_sS;Sb9=*m$r5%Rwjj`-Aq#7oXXUs^g4o^ z^~{SLwW{W-e{WTkJ4k}g<_iPYMbrrceGaJB6-X?S^6v}CIaHlI$d^L~DjhDI=tSTo zW122&JoPpSep=ua{`XHuRrnpNLutX_y^)X1Tr1T{`o7D~hsRaM)PZ*%X`d@`ms}%? z7ve7m=Eaukp8JrS0Gjg8OP3i_R(EYg^@!l-dG^J7PkX|Wy1fsHPPt3_jUXlsanomrF7lDY_Vk_}I5I7NqEb5pU<5o<|MMMaX3bYpFKL8PyuD^niB&?ps}-CA%KQZV3Y>_rwP4O2hp5UJUgStKl^bpUx+EVm{XC=$fojU}Pu* zvuJ*%KBTR4272-I{qx4d^~G$1j@NjpWlka4t>GVFEei2cfDrM$&Jc1FV{v_k^W36; zkyIOS@P+h)1is#ihB-isJ#odyne7&AO^cPy3+HY3F@u9IPxF+2jhx<#rAy^jtb!f=RL#I+yRKa1zx2c-f<Il6CMbDK?v)}=t=X% z2R3uT*?9Q++SpceYQnJ{A6$s0>=1K2h>k9^z=HROAx89b+{h>A%d}3yT6lq@|ZsXAd}A; z7@E3wzfi9skFnovWN5)j#W|?B6@VebHDP&1STD3Bb_t$JFf>n{=N7v^ejsa}n(OcL zHTBeRYqRn(6GQHQ3JJUXL(c5ZCtfKAB##fHQxzm{QgSX_bUYmxEu ztJ5Z}4+z69_5cDpkhuPXs25djUP&N~*1{u$XNrYAE-~4u8r0>1qdzyhP!rM=M!W@p zb_8d8cc)EJN{Z5ju}Q!TzH%Yi*@qdAgy|AkD>s|b9-VO2MSMhjWJ$Neok5 zyG=lhI;*t%51!NuUcbtG`Xb+$G>UohVg{vUoSIr$p;PGI%+shfyKKuI#A$81F>keB zmy^_Ak5OG77srpLyWG$ro{-d(_LX2p;?LEBLmitOp?zfjTNpjQ>u2xz`1slCLWJBN z+wim*8yO^N$;BU*=yu)c6P~Ov2amN5FAZ}KjlN7byd;>a1f0w`t&NTIuXqhM*h+LnjCtun5-J-{09^;$aYFtHsVdo86n$c$vf&L<)0*94_^HEJ&rh?$&i{rl_$2F=+r1m{B) z#`v!aLS2Vl;gYNcSEoclcDKPLH&u9Xv8TOLeg2m@RAKB`j9M4 zm|xN?E*B?PSh9?973w};=_`WHXQf_uDKU(906qGi`~Wt*(sJ|WMXiHWRG1CoaPTw- zrm~xcrA(H12y=I6hi1negR9G6`sG3ZF|&gUy`cpfT#q7f^@Jd{JQ=)65iZusdVpOo3)hD-LN8CYtD$~33J-t5w2tp{jeTOO~>hm44LGf%67&+ za>|U3d3FOQXHy9Q^E0i$vG3TeVbXkOtc(1On#TVI?wzTghSdlGhQqpH!DB4+_xBMM+NzN@^Cwrl}F$tGO%l|{G@)t7ATy~ z$;>5Z{*G5nw|@$D%uB&>;)x(V$1&hyS7{*kCeYj;7$Jf?44G#FXW`>sf&B~JT4fM+ zz~A-w{;;Q)L(#3I+Y-qWK70Rqhu9Hb{3-}CcZkhW9mCi%308>F97=)f`P9I$Vy=2L zMca2UPxO*LhB$xGA=E1Yb7XzI3Q+Gdf<;eT`b`k8A#55N&-1Yx0aJT(ZhI`y#Zi&xxAp^(Tf)Q#o=3zS8v=`qT-dKet`~4TA-heZL1%$ zk+j^OF0u#(%xk%i(Jrd5<(&$mOeykh0eNaDUg92>)ov%*?Th~=GkaO1MU!Mqp zbkNmi_40I^4nDv`+3`{FWS{}2=#*yPUa6`3pg!!tnBSr|Y&3V#T7^|(rd#Y2k~8x_ zq6v?8w>V%gj|-K>KzNC~i8Nh>vGJWRT* zd-OTOK}5KbM)e**9{^nM%X?f^8A!w)95!&1K%s~&P4m$!jF@ZNHynuSMR!d4!ZqG4 zSS->cD1+Z#?Y3zHJ6p#7PK6%@m#rtBt|%pjKGBrRQu*9m=DSx^KOY@bw&uq@58^uwH;)XeoXa zb?D$B#BQ_^9$ttL<2NR{YNy@UiRf4b#0JmGhn5%OTR4DwzP`IIsG?*L8b+3NbQw~ zV_})8&+@w{!h-J=TOq`OcyO*`#ugq1!D_=<@FA0zN*Tuk;nQowh5eV%{5J`4@q7zG zgh1TuKonILq^xTwr_c8R!6VMf&?|vVf6V!l%)Hc`Q39R&yxn+gkfG>SO*zR|8Tg z*z+z|34w#Aw=Tj5E{|W!08%_*FxabIVB81xW-a8LwVxsBrW+Jipn|W*tFyY~m<6Dl zB8Gt28zn1u-$9RbO2Zu%)C|7M5{}xaXQ?DKo4?)BOBRxTqs!$MotJ;jdq-+>U z%c8XOPADc`SlAY5O!@Kq*l-~EbbWh>ga|I%?P(-n{<4v0XHkIVC#`X6RMC(}J)jGv zn1te3wrL!%#Jkd;%&PGKFQON<173p&;hbcOX@#NAKnZ8;+;B*nau-P2Te`dB^CYKB z&|54l!o5zIBya5VXn;%VFtZPFnhf&z4oGvy5RUb3 zL?9v;0Ez}m0Q-B#FCzunDOzi*^>Q?_Za9}|a(OuW2h$r8wC7Ym9$(8w{cTdJ$w*r% zBvO@Sos5D~)w5g}Oyrs6%3yytH!!C+jwFA-bX*!$f`*LKq?7VCMlW&YXiRvlYZB5I z9wH6t(!y8hZEF-HoHAT(S7qhw8L6zpQt%9t(tKKe4rE<2vitq{PIdg$;AyiXk1|An zOy{TY=$~Np!U|yGHO0}|?o%J*o_Qzka#lLl?D`PdmkNjHLZntQ_B&PT){SoCm4VaZ zSy59m5bMpo--Y|d00e0Uv{8vBLT0X{Y@w}vy~6KvC?PVvwt>?P2|_B4(6L*3JT(4T z@cY-|Cx1e2bE(QLuve9W!^1sUU<2O_WBBBh!~-%hmEBmRG6t##mmh&PwSS`#&&|Pk zxu%D-&Kut72&_dtfshSp!;Rl%H0uGC2ho<8jY#h%PNeIFaYASgZzaRYZ+AQnQHXvH zQA515Xv|i8%4pwbqRI_Vo-@mw5gsF^+mGGu;6EDv2WLXNYzEw#&A5i+R4eg2iR*l4;w<4L)r~&x_gjR7wtnb>OGcjKxK4 zmANz3=JdX8Tm*~~jPQ6X)#jYFW_IQ7c-Q^woYS{R*HzZgrVIt{HqYj%>k;4_2*qNS z*Cp*aO$z+aT^)Y_^H5YQ8j;;pc!Z(7T%cw~_#$Zrn?ckNw-OyBP0W%)>m!BRk z1+r4SbLklJN8lim+(5Sfy^fRMGzi9QR0^X}sD0>g_7tr%p#q~lJiBC%8mV%T3N)kI z!BR|RJDMy4K}N+xWR(ek)*pfg^k?NthY%S+t?#cz{#Q2q-3&ucAzLDzy4M$jdD-`8 zj1QK6B?bpCjBw3tLQ{I79^BupU+$ZVvFZ?%e{+YzwO1kNd_Au3N%^2pu@VhyyGiH2 zx#%p?uPk3AdmVsm-^bY@T#cEMX-6_T$R2!Az`c_h?h>_-|D#*Q> zL<23i@UF`-PYu^>F=44{AFp04DwrEh;B>K&|lW)|E0*Ycxm}kM07Ar%&L3+7X43A@-yqhZ15Na5;=CG zqhZQF2T7Sxz9WT(8&l591)yoGm~R6>{RW)@k4U00QQiMV&usy)y1WM&NrIG~@fM-j zp97=^Csvl5RWcJKHfMt<&jl^0h}ar0Ly;otAS}Ti^yo|NPr0IVp${o`I_WqhintT12;70>nS`$Rnd#v;K!!%lD=14BmH^6PlDah9%j&3(SyXHy$*#pVUW}DD|cs( zc6$s_f8P2NCx?{6{L@@H#=gh450XF+myErwN(2y&o|m9>4|gT5TZz!toF7P4B|E(` zWH{&Y#8fViv8;Q*JTq9GsurS6(f~C;%D+Ztu$eYoZgUnZo(MKFN4SbV{=0QWdhu~Q zSRWDgiq&oG11$Jq{nE5ueBFK!Ya(ckb7g7TM`mc^Zzva7I)>Ab27Xh)ovJIoyj|!T zS(hxmXb=VHUYO1Vl%x=M51dx~sxN&6I9p@~D+vXhd;Fo^)aUi`%6?hhpU2lcgZ5)>>i8{+N1v ztQdMbE#pgVhs1ML6ZQuL`D3vb)oY+*J<4-P)s~JM8?^!Q96==gS*9D%C)3=9gfFqM zM7WlSVB}fe(DYF9#jkqYZa0*(rC*1(vg+n8;|XZ&ABiS+<6(I4cRpl1;|j{%rJjx% zBC|i=fv?&l=*b`FQdO7t|9yYV)u+szuhYV))(n1_#Fm7~*bK=paizUO0gFoFvB%ii zfQCEUd7g&*aRcSg-gSBgZt>dLVMWKBq-GRPmTrFrsbCpCdDcD6$=zLOLJ%Pm$Klf4 zt^DKOUvBVQ&1;M#yOAPr{1G>3L;`b(J=7Q}<*X@U~rI(2CetuEc zj7xJvs3a+`%GQ3%1|4QT&5&G~!~Ih+77^(eS63jw144QlU}hlXX?S6np6wYNP2!63yB`)I6wtOlAtm?kud3zg>t9B?y3RJm!+N z!dsRn?h;{5Dr2O;{C7@r<#~9w3UqRKVlVR^otFiRl6qjRUAf#{=bS&wYV6{^H{G%j zow+L563~~Gn3e3pP1P2hiKRQ+WwTl0PL_8?J|U|X8{fk6@CKH!s{M@bFQ}&mc4@vB z7|&QW(DmoZeE!Hm^OVA~oz^3>q z{BbR+#bTI4lLi-e}^&-xXwL=qHwegS<2*0ws# zk@NNqu2Oz3A-Fs~^}C-aG@*j`RCqvXCRmGZ)E!IzE-sRr3q|q38V(y3!2O|AxZ zwpau44r?4m-B%ie*fVT!P%k>K&~5!+C^#J48;z;d@REKdjyK5Cz9UVV;27E=D$ndDP{%H_Qr7$mpT$95PS69V1bU-7}rBJL)F@fo}-ZN{jBgHMNW zsNpfM6)__XTE{=GIO9j3Bxz!4u=mdQJgc%RF39W-DOAly?AZHz)o(d|u~cjpEDak6 z<%En-h?QqD71P0YGny^eV+Vx32XNPk8XUXoT^d!&O?RslJJ32)&z^hMrzTP}4DW#7 zVu+8m8s2@eUb>5Y-%xTbeA;%^kX#h^Q^DSdmHdp_EM1Ar{1N;=`kNX{-%S%8pZ59@ zvUIn|eQS(YFMfU<$n77`he{tK^02zN^-F3&?~5x#3F;=c5XnSkycG|KAY#^rGpV&` zAn2U{jkw-I=iA8^Fn;I3`2R-2+Vx^O?h2F&D zcgoz%*WbEaQ`J3``!}@X)<04~1g=&8D(5+lp4-d%c~x`BeE^v64b7LVx~f4)1Qs zh`(++DT;(oYu`%*BcvdvuREg>HQDNgd(?Idif6rG?%N0%>MhlK@F;vFy!#l0@hnW0pHTRq}+l>w=yWDx9W5(BLQ%IzZyS;pG3)aH!! z$`%#D8?fQ?18tv!ID=>0t643~$?}!vhYt>y;RuxIDstV>^l7IfbvFu)y>q2-hkuzu zJ!(iMXyX)t5(jciq(ce{lw^3m>S)sUajAX*b4iMi&=DDGvaWN4yHqPTU~W5T(C$?d z+NRf`X|Ufcq3Tzlf@L;JZY`GaXh$7XGKATmE5%_)|SI9WE&2-6D08zhF$UM(wCKMpq~W#trax=f@vqwss}^Mx5%tG#33vOJzS z{*?Yp0Io=Wl&WtlV88x(frnRWH0{>*+T(qRA~b^^6x<_y0tu&X%)v& z8jq6)GkR!>1f%}G!g=M77^wASZd4U2cMD{g^z+hX6i}eyEHfD2Q#=!jKw>=Lwt#A- z%mQ_--rbOUX)!GQ`jjg^MC2n&yADjs;QjxR0p+CKP!q=u2I5>G!r&RtJ4J*!Ze;dS zDqGYm3e-VEBC$Egu6*+|CWX=fw)6xdy8NRpk_-4>p;cGq*rCl9w3Pi=)Pl(s{`ihi zk2p+A6bey?-tfD*^79BQUVEI=(Q!<6OtJeBR9~47e3$nRZR( z>+^RkYBH#MJk9*DT{&a)Xuk)@;ch=n^qLCFU=F2O^aqB?_q zsGj{~+J)TH7z<+fc?cTQ6QFB$l(@|HH@aTH+T-B=Bk8g3p1CT+H?fy_CHC27^qr?H zg$z&EzM-0wvMK((4%EwXF*2D)W1GT|=byk96~f{}`etb-b0og-Z?N~l58d;WXA2*` zNqgVUbGv$zr$GB4$}WGYOkkOt+TS$6F`_+cN}iCV8MIg+(T}M0Pv3qC0A1_dZTc%} z8t$M6Ob6fqf=Er+2+sl#FR;BwhMkqA_f|Mm1NQ!!fiv_CKj7%_T5%$^E>;$sjlj;s zn*aaYJu=-wF9*d|Cz@8Y@9A^ytc+E?snVS-=xM1p%W8o;6UY_!6dVXK+tC_M`0q70mN7vY8LeelfB}CIU(jiOOP`bw zZSD12p4vzbk1DlY!_F(X3pF1t4I&z^cy-S4ebvHBtXD4{0BNO|9)oUpaULp!mebt6Cnn)Wx z1YT~K68-I%;(D|v6deAD;m{?3O%L&)GR+NrSgid)MicmuA!_$~Y)C(Th9MimUv;yb zmXkY+f;IX*B4Ph*K7;nuO9_HhVYv->cmsaT=KLA`(u}l%7)mwzrx_(Y=F@Qq(_l$% zP&=}p!USkb55U*vgM(E0KmEt>zpO0+GQ~d&`PLRs?NFidr%S+A7M*t0mHyF6!au=3 zWT=m~jDi_YkX5JxVH{bd7z4t=7q}83D~o8dSkSbeXeTL!(|BOYDbp)eaT@b30tvLW z3G7N~F*bS37euy2o-#EY@u0f6;z`6j+B^ufUzblH~KQ*x6+L&Sz5R;$*QyO zi4~M>R|3FLhFy`gWiroEm2>Pd&cfCe#T%;fvZ$ml&Ka}w!%6_n{K5N05fC@$A6_We zn2%Ev>fvz_MfqjGr%d@7`K$WCh63|gTn)E6lvH4dzxDR$X|a3tyo3QKU)(T z!GdVGChcmOkM{3;3Y%_q9M0~qGouFYnjpVC( zJ{z&O6~Kk!3b8?U_aT`B;&-xh>@CEbgmZ!BMrYi(ebXndVTCUUMDgU2p=xR?FSShl z;)@{jWz_Zf;2$y}0Io};me{1o3QiO0f@66Ce(gARh;PX(fr+b-pZ-N_ra$;!5h&gb zz>%eMDYl`*MN>rs&!wu4NM0qcdX6t!>7GB$5gdAjWfegNyhUo)Lr?GwfnEq9OrKX4dnh? zf^__?b=!zg1FPW3LiPC=iaUrak$Qg{%3NvXmORgpl&uk@RtfCw>hxQ}ld0;rjw}6$ zARMvu4sz=puBB(=t^`Hr=iXz7^ZcKt<2aOu3(rBgb?rFMRYVL4w(Mjy-))LQ)1N?T zsb5w@+PDdShe%l@%(fMEVtD#UO<*GSIai-Jl~t)zG z=y%qE-XC;9+}yEkv8y6d7*W+J6JO}yq*$H$_oD?A=k>CnkCdO1!tlnkOTwq#6m$!%CD9TIQ zz{wbXXqnT#i3(Ni4LL54k5oidq=E+k`QC;8s<%-Bg`;V6bznJSD`|B^JD+ui9x5e- zr#n{81tP!3n-kv5T`+Rub-fkFMTqe`<4O%>R`Ocerk7OlH~5#Y1<|2HGOA2oJ{Ejc zB^rWO1HuYd_`^}lo{NIwB0RECJ)!R%Ht~g4QFX#cDDN>m__&f7K(AgLbl%+-b=JWK zsc+(XM+CrE6Lt1dYG8&6q#)RN@@}I2$KtZqK}fn`Z;8pA?3Tr6uMB+nGYS6jZ4nY* z`sU|SElbJ?m=lkI32aPK#P-(hwbQ{)?UTrI+cbCOv73eygWyQwo%m231-)#{g66Gc zP)Za_IcQVRUk{RTc39`R^k>IE8sPk23-{D){RMK%kz3C&d{X`7K4*G|or#spRrJrB zEXjEJ+Y|?_eSM3GtOMV=o-BtP!%RIZm2bUIn{mKt#yVX6N1$F}6ZcTbY|4^~g zP%vO_I5h0X-g%6`G^ni{b$8$$MWyx#wE7J(3+4WrINYRxiJVxPByd2XVv#Pe_8gEv zMgFX|cEG0_9Esb7U}^V%R|8m(e9us|JNNQb&l2p<7mEgo3}&c>j8UN~YCSRU|E$Y@ ze&(D$&9*W?t2$nesKF|HX+;b2~48-&9sC( zEn>>Fx8?#f{3E>>N9R$C`!>^tNz`QaTQpn{ImzF_x#gEd@UyoRZ{NTh%Emttxf z!7bA^qAmq^5D`e9x6Q+vhKuR!S#S4g*6t`F>vvB3=4B|vw(rA)%H_r(5@MsS!Zbs1 zZvKA|FqmeMG#^Zo!PiT*lz7t;6E81-cWXsI7EGZ3HgVnuU>o6DnI5}Y+5JXtKB&8o zw(Q>7z}25&vEgsaC!QoUkSm951^xjEy(g<{;>AO@^jA)KN*KnjF-XxVEA`(7Vgsj| zaPEHv{|8PxOF>gpki+&Ze~3W)E>u9^SuB)Q{qv*!buFKe?Y4N*x*;SzW2w*q6HBU% z;>Q{n%9(Gy(JsMd$tH%lA7DF9*>~86>d}q_A~~bnrQ(cNyS+t_N%Sw}?d+pK{mbFu zxoJNighWaPA2@MU2!+qaGpN$scyf9`QsF?WXF1X zP#5tfP3b?4jHOuC!mf~7d~pD{J~#ge-41CrT#UYz@!@SKaOUbfqxh9E*1z(*Vqq6t z8k@6)h4pTVHm06C05F;{&iYad+G_ z?_=|cWS&hf=n$it3Zq&Rn+>=~Oh6nRZ-f#Bty;X4L*8bvaKo^`dItG_UR9{9@9*E< z$j+(2>lHi04H}QWe+cY?g4N^tl|C5#=dfR+IJQU~=+O|F$9z>l^pAV1us{!tPzCsTS-a9?0@>^&K{JDq-co*H9DFDO?y2cfWfI$grMuQ;N_pCa z(gPPQZO(7aA%po+bEbPVKKalU<~ap=+Kirf9rb%GkAm3%JOV`imJW%n-W>bf*;Z=A zlZxg^HNql6xBL^wU%D(jf9&jA94@^1DQ;7l>M`pUQc~-SOcTxX> zPqtl%@WJ6BBv1erq86~-bk6F-X?k@K_ws+R!$>lQ|Jk~>hBkV&Yx76mjM#`8F(M%IbW|EOK!J~x2ljBLve29=^i%_b^%&6FkDQ|;!#V(fA1@R|Wz zFKieLseJzYEUw_Rrc^Y^BtjQZ6#;-+@I&s{$k9p;o)=m%A7IY%Kc17JJ4=+OlEd&z`u`pqi+!`ZmA4uj`sV>f}xDyd4j z21X*JaKyfrs7c+1q>lrg$QZB@{#9yQw&EWa8sz7-Zi!CyZ(rwOi9A3Fr`hQx8{RZF zf>y;1V#P%^x9biDU2Jr%1ke) zj;w+Sl|DGp21%B+fvWM9i?b9vN3L(zWcJKRMjV5|bADUIJt13Ku&}qCfR{3`PFIkG zVtZsSSa z;+u5kurXVUjVTk5wKq3pi_Q^;9KrXuQ9r_-~kw#ctN&0AwsbX`0KuNakrV0 zmH+5xXjf>M0Zymr!PoL31s|L06pIov{Sa~OzBdMGvqjM}bu7=)vE#3)S zRzy-kZyUhcAIHR!#!Ku^2fxSvxExHmmd~4Eb*FK_Al?5r?Y|?dXFhAKfSGa6uAlxx~c#cLYI`_j|b1bvWe&1{>+~wTM z2{6~)p)c7{^cT2bXE`Uni;wwtG5sP9(_h6j15hM{?@hV)dB)DryFb%|Q;%N2lGk_pO!I)>s{f3N%lwC~)YyGM~-qf3*<;A}~)LQ3ke?^_zp z&|_|%g;`k|-r#{F_Rk+<%eiZ3EW? z>B{540D%tfEgVA?9-8t&gJK}?X48nYf&Cg#aAZ`mVdfwEEeJ_;Aug`p5CZ3A7){Mp z#Y2&4t#|kraPJ`Ld9Wl3(NCXNZW`Gj)J@{nge zt}Dweg;J4!@>9-+m%)~}h>aJ` zoxQpersf;VDIBz3XNHR^+4q%e=DsZ0U2LFSI#hqESUGy)Ov2EBcZl3-3$aSIh!F0p z&ZU9Wj{&bn|Bd_xToTzPFnPcS&0l#IpqbZ4y^HZ^3yGV?pr4an9{3*#_c1-S{(LwD z-doiE1hfocfQd5c_qn!8il6#ik`ttyJB$c;JHYR;=m2RmzLC@fy(0%6u16y@z~|JX zsH#v&7c&R`nG0YIy0p4$4HcDHdb5n^f?0ODBX{rbw;VoinfLu6kFLb$D$F;6aJ{Go zE*My_806k#k80{&ECyKfLQnU*g?C?SELt|whj9?9wRTR3m-5n=M&0E3L8xaOneFDvoc)ZnV(4YO3p!J4~ez(|e zF&)>4NHdAQM&{t3H9%n$MZw765b5=3>#=h~t#LKCZ1OF`uZMm4;UI=!5u=tSsq&v2 zT?jBTiIpy*>hCAF^6K3LhZG}v!SvP|w9i}*;!R}b9$z;01mVY1>@@vioryC<;*F`y z!t7*278_`l6&K z)7e2#aK)u^mj_Md>ljS#AZhRb%IUHdV0-3TYMH$Ck zX+HJj+=&<2W6IdncU#K^S~y>*J%a?%Q7%UUAEU4Q@H$Ib@#i+sgn@ z9&5C$*pYKOu#o@HBM=aht}tW3`@KarPC?3)o22}4APl3LpYd&Q;L;Z)zXy{YlMY#4 zf2EEKC198Cl0G5663aPKfs9vJ-hI(m*-q!&J~O4ke0xEzdA0KS>TI3e5_WfgHQ~i0 z7YCtSoKWwdgI7+TSNe8&8qUJK=8>e4Xcu2x$^kzx>NQ* zpf0bUD(oYKwD}Y#7Qe+xnMjUrO(t(rI#g8PEi}QvNUF^I(PAvi`OLbdYFQAn++Yw5 zZbfo2gdZw{Tl6`!B^YB`8@|l}%VRRSW#nj6tF1W?GA8iX0by=ZPS>AIPgk_M2j+eL zP6g>Ks@OQvAL0O3&KG|VA|T$I-_Tl~khL)Z{q^5rS1)YmY}zGh&wqD|3E?R`{*W57$>Y;FzK&26uimT^N>F8!%KP} zvs)lNYjLfk0@(OGQQPw5gsb`co4HZU#EI-_s^SJ%ddfnTc z=@0(9MfAS07TdvQeF>re@TtSfcuI2XaBKO;IfGnSH^wfZQtQ*N9?E^j2&eruTiX5c zY;2i}1|8Zv0>r*eyD1$?bRlmksSJy%QQVrFThw_9pe8FLH z@9eG^(NC@`H^ClQ*zanYAJ3bKw28~`nq7{3|9Ra*p8H5IaDf7qQ%Erg9MPb3lv(J| z7p32~vJ(F(3?#Yv8^grWSo(l2sWGyTr1;u%N!#XzTvkYB)Rr;%@#@YD{X~_-p$k7GfX|ORbE%Fl1Vms+v_cs35>NUzIcp2p8}rb^A-bZF4tfIDy5rVN$qzGdhKKo6AZ%^{(cqg_^(_v}bG7xi~W za}*Ua+x~=~vthl2_jr9p`C7)VaBlx&;*(&TsbYFtcq)lll7n8C>T`g~cgQ|%2yD0Q zhAs4xnyE*p+uNV2`L{GR!jfICC&?%0+*~_iic#Sjzq$S}_5FGDFk|4rSz(36^A*?x zEdVBk`LLWm3qNIHL<PnDpHysLLDUCWCtGzEM;ZO6ZJi>aOcgIlDD@7zb*pq=RRh78=+9LFHd< zoeP8BCjVh#GcQXDQSQz&T+4Q-MOh@j1&o;)6~H~u4LyTV*a;3aoKoYQlAR7%YvpKy zxRsYZgKyk?|IQNQ1skww6V_@z$nvG!ns1FRDH^7`Lyx@S>Tj)J{2vO&O{&d6t;ztL z`*9WD=mqjjAFm%oMYEGnq|FNT3{P}c)2?d@AWwRO*atLT+`{rCWkhs4=qyX87~S!) zDW>v>10OZx-CE%^$NTajxN?#ANe;DcK|S^9{ARn<<}xO;^D)HTuWx}w|J&NMcCIN2S*oGuPyiNV$mH4=9MxU-oA=5 zQx3t89_G}b^)IR9=B;6no;Crmpbm2lfqf3cz^t)fJpJulgi#U_*gG4JsjdSHX*YH>?ZOtzz{SmQJ5)bJ+5ojVD2dYt<7$)6?B`9oIL6&;9e zJY!JYhl(iQ>*wXThf@P=6<+8ZAFyrJj$`O1ebS)}HExyq(sFLarJ*gzUm1Z9S{W~eVz!A_I1|g*T9`AA!h*C->q}rm^7?X@BL2+S&uUxk5zB6X_PvAqWeda&2EV@AMBCDHJ^-lK2kE2=@fT!ts59>4*O?<*@@ds(DvjlFHxiX!AEOB&h z5Y=O_DU&r-(>!!hY}nteNy*4=Hf8(>LCF8`0OBGp4rUyClXy*Iqd9pDJ}~!5L5oJV zAVFptzrk2Ipl=CUvV`tf6Vx@d-;u==zp0-bT$o;p>7W7bVmlxi$sK@d6?gz%`S$om zmZeiQq4&!e&f(46_KFWeGl5Fu+J~IUMBP1X#fr$N7kltby5+jYR(1BGP%Xx={RQ`vEY$wUc1$d z1mJid2#75H$=GRC(e~}|N{;{1AFq|XBn><#$7l%8G&{fbN$%Q>%@~chsFeOj#6N$>%3em?9?E4+k8Y z!RRW$yPPc?!f`~9CT zSW?w%LIZ*>s#}SW%yQ(H5Yq~O=d`m_90wLCjVm?TBY4U??1)y;PwTT>G*c2Wa50Zk z5LEy1pjdv0JD0=K63I_TE{iP0jXruav!(Hvu@Sb>o%|Lfp83pe(Is^C}u;MfhnxLW6?Y}RfoATC$qDpID%FtDY@~^^`JQ%`rl6~;8 zB9!P1Oj|6Y7_qnkGK<@_-Xe1`g_dl?DUh{_Wu^U7WR!8CF|Ks4bozVEd8z<8**p?| zO9YO9Z{rv@eS_Ms6g?63cR_R*3Dh?CyRWbaa0|?#D?hVf6P7@|nbAOw?-0&IbGe8p zlJocvmN`*rvW2gQ_mT0gHKwYhM~P+^h2zERA)de*`03)djS1hJyU5V1XdA zw1|Ksad1B3xE=%6FO1TudHg8NxW@}e(VP7M@!5~asrCYwh6?E8b&huaMPLVOYI;j;r@0hPgDP|U3pcA1p~xG zkSPpwAYZ*K-^gcBPH!xx^JW7qf(mUKqD5wErJZ3(*iT(!db&+{F?sdgkRk_k>t1k% z7O$>}@5XMAXtkmt%#VQF(N`jhyA57*AL@wzbl_vVn{IrP3@&dpF)uILpl|}qeH@@O z#uSXGyAg0!EkF#68Mlwppkn4xVM=n>K7u*`F@O zo+GsN%NEhX((Ia8g6SNmN%?};A%vs3^zPfkYcVUNsS}3Z=C)?Ql{9?E zt_^D|Fhv;)O{M5$mstB8h`57Mt5&x}m;j&++m@_u*geX=shf;%lfs=ADOT$_kGYv{?t*l*u;Tk! zNZ*%UF(8TE1_}SA(Ds<4FPBp2PRhYx8#c~Dy~1JhYG;|^axv&XBkk5g01z`pRUk+ld>het%RE+}qIHK$l&0rwmVI{pf;odI4I9Ux5=krRN@5O{Heh!OjL5 z3ggGOsSd4q%Ft}O{1A?jIZlhN7M8&t*O8`2bCgfI>X5=sb=>9c z-f|U~8I?6SaF@}8B9h;4EjYu&KpZ>aNMdR~Rk~)Ku2|MFM}j_DG;?vH*8`1ZcH~XsPzlaQm6Nlb;F93lp}Ev0RZX8_{L%PMBt{m8^liFBIGmYh_GmSb7)}0Rb#%l;^Q0xt=(SCq93zhpxlx{ z)xz1iW$7djU=6-NcBkPJ`rq zQD|dJ10$B9}%vBPMc|uB| zGG!;Qa&pa54R82NKfNaRQE-9ZWm6WB(5LUL(Ighb&;O6JXcq> zRvudF|6z5dgt_{}Wd|8?%)J^hoPoFVVCevx{1A28p*?Sq6BQS0BkJ`G7f-I{{!tvu z;ECWm;lC;*HzaIzSoHvkJ&t}>)?ueD$ov0{;Dvhe_9qEAc+{Gl6_8?C$tx~gCFnf~ z;Kd;$6yn>W2teneq(@p8`O~YknN1HpLUp3(?eFkz#VQT$u+~ zpH!D_gFcvlt`OeeiUx==z_2EJD-Y$l`nytwnWV44H^kRzN^4166^tAus0)mMr1Yf9 z3{O_Oc;1jBoj>`XNEE1Yn}UQlL@)-N^^tjZi#RTeqg@lZyTy2?8ADbH{BN2N#X1W_Y3lAgHGQA6xaG-YS zJ8|d)4ZP}X(%*JDZNIB?4&pg#3R6~v#Iu`#Qzos4>xOBcd@?rX6`Teo@I|0;Ew$5N z;2_?eRr%gz6Su&IKpwp(`8FT4giropecws+By~_5?p|g+ux^F*DUr-c;yKCm`uLCX zO=hz6r9%S+{3a&5t#isX{1!E{pX0x=+VzWgR*c=%tT0v>lgKT7!bEl#K=s5na_h;A z$_rB|JgBWXppn?$XJ!I`8H5K*-%tX)+>DBT{dTvUh*jcX`!>A3iCury)@bBQ#c6qy z$LZ!HTfW$cOtL+Hwo(uysMAWOBP|`+u)>+EV0}6e!~jQn-N0IRO-69>_Ye@yl`@^J zum-=V6)D4nfr!$6iDVV;1C8Pz%h-wG#(E9vviiF1H32S5e21QdR~tS;Jg5?`sf*Z| zI0F2Qc6F%wr1(Y64IweAlG3}cVyBHuGV6@@@-N$;NrBfQ$gzuygJq)V^!<3we-Av$Hq z#UoZ^A?FSDrt4bpX&aB+hLO#CV3LUx1M{+}Ku~!_EUyu~b3CiEqf9jCCjjx#wUw?% z@X1n)&kRJn-2A#O#C}?o_C~F}7W?%0=ITrqL8=cDUZhu-Ty{K> zAPI}U@f$eA3mj4cR*B8AT1|H_1-qT+>TT5Uyvr}C(x0tsV_Bjm0{}ac(073Ic|fSg zX&=C|iDuM-V((ndad`2`S;m-g-+{k8CXxc)ii025xSe~vheTN>F9xlRId-8{3G$Pk zY6F|aPeP<&bFg5`%Dq9FgHQ=#0rqPcfnN9FN4mtCxXr=4j>_TsmJ(mkL_kAIE7J+`O{FJhtD`%)qsvD>Yu zzrdWEbC;ZUfci6N(Bw+Ee6Pqip=h^w?e$rMZ5p}=%UWZQpxfy`p-Q#6NF~=tbhiu8V29>;+yUrz>i`vE=bkfXyj~!vzNVH zkSx=O8Zw@$*jo!g=)#=cN*1H-;g)Mnm9&BNK@Kn)U<}d8a=>Y#1AKUw*ECtB`KC&lOlH;Um3t!` zLqTvY@_j^A_h-n_Fn>x!w(#pz@xA7=M>$J96Fz0A%i4BN4`m>APuxO=_0ww8+FjBL zNrsLX2^%TPY}H>}H5P@jb^48X^vpXXo1oxs327@(2>$={ZX?b-7JT$z$u~8@C5_Yc zL27zcO7vl99{h^D-q`c`uLZ?f5`uax9s;V07M2?607xWr zm?IWPGbNq&>8=7Q`&kH3MwIDa-=wPKS;|~7_|9*NA|^e5ix zW0}`uYzWVal#hDAjh=jX4iZpofQU5TkTEUU z)2fgKIzl{+#WDIAYSk-yU-g}VVElFp2r@^Y;%*RSlL_*FI1Tswwfa#R4eFn6t1wzc z!V_76@%qi~+#L=MZl$hadw_r8l%2I3=O{@xnLq0v$N17GCa$9)Ha+^ed0)K`)O``?vAQ`n!QfjAC;GMf9t#=14G~wY_|%-{-*HdiXNVTPCWmJ z5#iB~qXLSEpp-yPPd8F%}qsg>VPD3Z-P45!gUgstcJF;61N=?eGlNvYxVgiCP zBRUdQG~~m!qiQz3b$iC^+?>a?MY_8u}XID-C9Ct!DPj{N|a@?f}mn-h)zvq$#%6* zy9ElA2z>k((zAC@DB7;j`Gh4;thM=)*Z@){2m?Naw6njefMqLL0p?V9r;Wz%I-v&v zwBg1JPCEY0d6>lfyYwIHON=@qQw5Xz`q)aiI;g!=zTgU6dq&B?T9?n_ZmLouMcjXo@56;}Fdhj6^^KEL+~lXP zt>>&uM$BSDMmaX?)s*GZy~o?ltX=N9BfzpHmfM7gYZ%PXKjy-*_pngB#$95YFTj*@ zESj8_Rl-W-|9Eo0?ZZzl^h-dUeJ?tG;-S-&An8a8GDGXSaT-m`4Gj5Zs}$~N4IG{? ze-6=J*J^mknGEdC5+iIYAGVHsE)A@?c+9}*5L#}Jy zb^gkZFU}@@9({5C;H-)>jZV~i!o}I-jKC2ue&@s;b9A$lS{T^OB3_ zIS)fk=~r~~$3rT$pN`y)m-wJACHlLtd(bg?Ql*RY)URud{yn~sK$ojKZxkQXR; zcarSdT@p1U3ZK$!z&oq= zs<*;1%zG6&)yHXyI6OSJyKm`a7a@Y-p80Ww9OOPvSWEoh|uIBw*6rK44^cZF}t_&2q6Ylf?LqNR0fm>#grNIM>Et%C;x25*h z)n93qMuwuwwu>JuoM@Pgq*zga&PAp(V?LUCn1))hSql78sKhyg`m|3TfLoKomc+|? zEvLQL8{q1ek9O$Lsd26XxORS|TCzFLWao&@l8|)Lcwk3iB(b6U7ZF4=UK!0JkJZ3Y z6_V7lkF1^P)TU4e@UR#I$~PGtwzG*aD!zT+$jw(#`>$GHIyukQa@KHhJfr*fz4T5A zwM&99aSicW=!uk{{k5iH`DoHQR|rNioJ1pDHN#j{i})}u1dBn<#XguzHG0@SfgZEl z{oH@XpP7)XHjA8G(|OpdY2;f3+TR<&R@vh(XIOIpQaIce7IS3+c$q6TVL$)MS{#>< zFcClfMQoVd{yVc@-oze$ibf*TWZ7%-Et>id{olAWh$9lLF&H0$Q}3XV>F&Qa6nd8N zyGQ?3*(-$}H;@HU(FNyRW*%alaQWY$Z7L4e_JDr}Jtt68Ib~|B==ztOY|6&jR~4_$8jp&00=yX0xZ`JM(kMj>2VN=zLc|j zy##Qt%EA!e#RYQGsIUwqVbRHZ2Eqx#r5RbI$m zWvyEVeg6_H-(CZKyEs6Xy!IG%46sZg-5nyfmL*E~YkVU!3eCf6)`i_17`456PYTRb z;TbP$-A_@#Dv#W(dnm~Jw5eFtXE?6-QF@@<31J5@5~B{a8G{Cmj;dpeU=Q7W1nO?W zOq4ma^!iD%v_VxHkzjH?SqNk>GRw&q>!WA1d+3;&L&;GSwk8D~;M~8T_6L$8p!D*Q z8v8`k2Dq72xv>kobqJTPxIUPyq0k1ll6d*<+GW`?=a%I3TMG&b+Har0F+;g=|fPtAL*FUD=VO1e- zs-~1DaH%`v;>Q}(p1=}$iTl}!T7-z10q6`T{uRSexepp zr@z7^85lz(3Hy#*xBSDq1_UvpIO#g9S2<^%~pt69eEdoKSNL^RdsGAAS>p zZ3fJ%6wEW=U=O%y7IBF(WV)`>K3k%y+HX-wN1L^f%fsB-?L!@2h)g&L(ps-WeOVKx ztd~J_6_dq=t3qZclX~8=nKpDQjlE)Z9E=>Ii+sI3?Z2GshWi{H%OK^E6Ysre-(!Ab z+l!ZAlw|`#vNg?!Xf#&aTnpI*kG@}8k!TYZY!i8xB61#9m6}W9`BI)e?SC7Y#8pt@ zbCfxnmR8{|zI>jmQ>+E2aS|6Mm98R_hkf<_y1#FRvKYP0Zg&>jx-PxU|>*chI)s<)W>$?Op;Wa1xpsg`ByfgoF}eY+t-$6VIndRW7FF{`gv2 zJfklIEh=7tIT>NF<~cA4c!%3?`%Nl%g_Zo6$tt!&{Q2aIY zgizXv2{%K^ODH5L7PA}fRIs#uBd^99##gV^@+p#ZRE{5K-~(ni>k@F6eH0&RI#f55 zmx1+x+@hOz!*~nJB3hTgr9n7yHe^`U;%<}{x}YETme;u_{s1aRQ_j0&$Wqc{^UL|L_J z-{G1u6~X`8tdJt5N%S^wlh;)%8YcQ_9)*Jytl@1rc+f%M4^IqfL%`Wnw^&uak|MYs@SD5K&U zi@Z=ckp%BU59OmARepF2$)b-*QA`{48Gq+fjAj=Tt z!6JVUp~48ENv5vrb|p4eL z31FF(BE9ca1zxV`vnTF9BamX-M>W1=0ZtR`RU?@^dNv_6vo~3ZRmEWGNi>B0~^q zWWhxxisomMiXaTP#DZv!umMQU&%h};;ggUhYnXMrGayiAzkk$OjC}r_AuMmd;uGZ{ z_5%8Tr%zn`(p_ZjN|`#lR{Sku`BNv0?g6$R~J=}X9AN+<)X$tYBJsQa;w{F13Vo>v;g3gnO8>Vhvj$tB^S0H zKcUsPNwVvFAZ4JJ{7bdKp_4mP5&(We!KZ;A+jS$1XO(!_b0jecpCf7Bko$f&Ol6Rz)PuC=oHV7H%}E`Rjg2hd~k?uz+w{#QmXwtji<9 zT&3>W+{2xL{;{@%G6h8orejFFC3%y>oM@W{9R zOg>`7yxne3sL{#3sM9rn2dFpKrFIwd#^SQTbT`dzQuC+U_|ce^Fx75BOsbGCNZ%90 z<2TRW2d97k7VmqxdwntMyG^jHM`2!k^vpHo7v?@Q&yZdI_~iMv(P#)uL^EEqVU1-Y zI;Lm7=^n8bJw#DwRhVB92uoGiY~tiIY^c4}=|+*QSj0ryB_=64o|)5W%ghXaCE1sv ze-?MHhMCAHVf`GN>LEMhsi&E!&sg=uYL_U*?#HsCe_702KnDuq>hm{yb294@&=cIY z-*r)*Y4H0oDPVE^eEWxwuYiW!`D-h@e=cyL&DGDd#^6)f#Q9c8j3Dul$V#JdQ)eLvbfKBxU=SGYd4M3 z*~683tJA=7P2#JHGwWC`QcHQErvm}2q}f_v&kOdgYM znwX~-Z`0)&Wa+QFHY(!ukjof1kPzNl!!oightm`mu!|y(CiM;;dDi$eDB+L1AO#!0 zH27-Wqk>X{_&6>4Fo@T>JjJDp-fp>zm;q=g;w)imnx%NG^Porp`luF@o%7OZEV^C7 zCzpBm)F+MSEPsk#vK(!v69SCP&Iu^a#k^Iw_qq(b*h)++BXNODGm6N47Ir>;le4D~ zpkV&6cbg+dK4(1J&NXMK%wab*hA zo3vEL1G{0l@RNdN5hT~W(?3&4#tp8E+Po$Ok_aTBTz5-oKHVt~)9>?XMpV1y%_gk7 zb^{%LDo~lOZs;0SgwqXO(p>t6>##AaJDHN@_3Bw_JK23nMABC8g7sKi?is;Gj`iuv z6sK{6J!qR8^}dagM{uwb6kfIxB6}a-(P*PmQ_S;RL}1Am zRHn7?s_krivJ+^ORt<=!Qn~<8#_8iel3SfvLpPR~A~OWZqXqL&{|zLJf^6$SQy(`yM=%BXu z_nh0^;uSPF*^f2?srP9p470AT&XR<{v?0mKd57M8h?H{uEKda_U2C7i?xbcX=cli2 zdjNiAx0Gu5Ry*~N_LPkItGvGTwJ?*a1{wzbk=`#j-V3i2n*4h1R^n!QZ(Hv&^Yn&( z#zkDBhMNca<#h|rFxa8LDxyF$FuV{^yD4MA2(F`zLKyQ(Bg(|IE_W3VLXhJL{~ zUT8On*vqR?jEd0>m*Jz&qc_*JM^JRl3I}9q`S3{f?tNy2M#WmZhR|)&$L#Jmv zJb)eW$6PBQsXmBmroIR}E3jTyJj>aUs=iE=eJ`PLD0HQY1;%XZ03Kdv))b!gHWKu> zx25*~CV3?p5L_amplggT|W-VlWz1p{oPHF$>GK` z{b*d}%-m*j^{8eByxKV+WhIm?0Pr71<{vSqM3F~OQ4}3K^k?j$0^uXVZ5$+a^w+%9 z`Iv#-55Zn4j&bvH)&oW^H>O5SqBAY%%pbDS=Kq>?PC!Yp9NmI_E$w>{Qx=k*l|s$> z%r#BOvgWScGVCL4)9Wm!Qo#4F3ep9=*O|N7bLD6cdDUg@!QOa1{~nSqebFSso5qOZ z2tGPp$TJ>cxuwi8vxH@*n%u)e%x7TD%k3R+*6{GuyuF`XQV!QnGCDBQ2z3EZeqabH zH{Lfwd~laQvsf-Phtc=!lM)GBnLt+ad+k~2f=at5 z^~Ur&i8n)wjj*_(Iho&3W7%_E+dL8+wTfLlCF*MKRjCv<8mtMR#pp(7FO zi_tFd0)F_d%vwWQ$~VGWmW3Lz(bvD6NFcML)KJ4pvhW`|{clSjQl77^JUy6N5yB8C zEI)FinhuFO?xA@MIkQg-ex`d}dRj}!31Cx8aXZqT&8~6JcfYvp*~W7>S+O?!>~>_v zDsvy`$hxUm-;g$vnSP^=rV&dztNgLW&kKzllbzhy@ZakSO)Y|5!1&t8t<((ue#oP) zS;JH>gyRgjCbT^P`0BW*8k9$6iMenoE?S$FVKcXvH0?Y*>oB@|PAP5>QA4fg-<+1) zRdIVkx%H9lhQhSF8R#}yT50LtxB(e#!kHG(8T!dt@6cwM&8AIDY}{xto#DjN#qP#_ zZ4mKfE-8`Qt!T2KPnyMHM{5a)VQ1x5_}W%EjA@Z(SEsrLA)clzG%LJjjYz3`&P!&mgo%8=xA%)}rVCxlgBLyLHSA%GxBph8DxBYX{il`)Re&@sjmnHV5; ze~Ew1`-2#b>jq2UkRi;izJCj2W-IObczH*OQCr*bL zAP@av>$;dJTF(9GW8<*Bh;1t-yqF*`>`9-HOc@~j`?agDs7<1q-ro$}qTwERi*6=; z7$9Eed}_^w)MxtUwh69@>WNK`>g`B8_9`bqGm6#N*|~O|2#X_8Lq+4aH(Y3C4QAvk<*?I)37*=JLz6I*9J5PAbsc7vU9*>6m-@^K&vb6eQLr1u(J}d_$cW(6^7~9! z8!H+p;u6ITK_KEANgCmBM$y42;pE9{&${&;$4!dlZ!kUQhFlhELV=do1%SQj(`}t= zzHYeH1vZHHrU)LIJ8_uTqp#k5A!o@(cPbh6pCXX;|6QbtrjVk7IM3~Ljry+BwC`v+ znS3a=LZKLYtv%g7?;EKr>y02pUt_2MAnGesz+NnkAKnMjm(>luanrGBhB3Ao z2BVoqmRK@PggNOu8Em3Y9xCr;eypel{E?m&+<^+!Mgq>E6q1LUVn@FYQ4Os~$6m1L z%(64i1^fx>J}2e{xji3tx(5PQDz3>K-diNq$79ZIeb$3IZg>5<<`5yowR55tNtvwL zv{0c6zQphA5}+M*9|?bONX{d1uh6aPwMLqM0#KYk6QhE+JH72_hA%82){!buU~KX} z(bZ6qRvIxCQz*x2U9o2CWXs;vjxRE9omCa7dAmsassL$!BF6aRfik4;RitjSlT*Qg zz|QUtY*Ex|;(|BHX5!NgknI(_Yk0SFk(j!9na1!{BO{As8ziok8f%nHHPhg_(d>=# zAlb(0?Gyov27Jn;`F23F6t8(^wX=d@`c9G5ahvkz_E+Xbs7-&DARW-B4Bd90my&hN zKd0Qrh^2YAemymwv+C3GYqJmEKn(gLaAu*J7USL+GJGcb*sN?LL1$o&B{L`z8MWdPw7)RQ~KV!>rw0PowcDHq) zO8(<<{<4g}r zm>((1ThsF=BfUX{Gjdg)Kv@wlQ-X(Pv-}cC&{~)AoYpH*PK@T;24?;aFV$pB8oKCl zhcUu>yoDER#=vT4wuggXA7Tck@wOq}BryG?V2<>ouiYOVmc+4_TH5l%{ADyMDfOc8 z)XguG%YuH(b(YQYI-s_X1(aUmC)5OUR1Uow5R9S1kr>48iz?@ggF+c z#${suLAC1+agfu;5n93i(zS%Aa524*ZuJFxe|^E3Lpf{Gc7>#Kn-gVzW}I0y0@_g; zSOR5@*C~;|ccx$C%whWy1GO2H`aiaKBu(vgapmg1HGGbEp&*5(K{z|nez~8#YYGwp zuc$5P`{_aIRYL&02Ze`Q5bO#RtnQBvL8`9{U|9Miz7+0PjJ#>aGz%~4g%zH&TNRMk z)}Un?jUZBg>|M)6*U+A7@Ujx!SYj-?#+RUP`@rrn0NZjxBT}Ec=0O*;Fz7P**515I zQF^GqCEwUy)S+}sgRf`8wcoJ7g4~xGJTbn3`ii}BrdaZrH4(kUA7UQVYj4Wd>pM^{ zk60j#SAVCW-6w5eIP>!N0Au2#saS*K zid^qaVv!j{V#VfiC2)a1ihn)X5_STOC_s3W9|6t2JdE?%R_-T(4ivrhaUv=o^%W0APvjYD_sF2bf}J-3uNUnlZ?M)`Gpt3a2w+}is{?~eQBk6MBf!Q=*3bVx-O~dd z?3AjWlrIK;H|tO+lECg326g`BB=AXhj87RUSa|v`1^PPqu!eQ}QX}dD@ZZEAL+%(l zxUsVH6DQ|?YYcm|c(@%;RcrDR`$9xLb7)B*> zF30(ehCRTqtvJo}=;dtcxX(@Cmr>D6JQ;VfOsTV52dG$lmrKI!moBBc@N=EdN=G)Y zjuAVm?Y)=LtRP3>h5;NPkE?Sr_r}LWvQaO6sVfMXwAy7sSa?JKNO3pW@CQCZk37JN zkiyyJQc3k~JNvoZ)1~7Dw&EHR9Dhf*2@K^&He4{MT)k4p-iFIF4y#9r0x*=Lx zU4Vo0Kc1vkDYZ5mg2T7-iRsTI11dEhd<{NCbKnh+>muX5a|Au!-h-eA&?8T4&Q0a( zoX6W%nNde$M-NOf>Dglc^R(>a}p2*7Y$Q?|WM0n|kmC6SyV@oBBkCw5dzMvT{HES`D zju<45<-(;~h`YK^yZp1jE0*S>u@~isKS>hpG}$}a@vf)1V_b21VjYmTNI6Yw9V^$<=vCc)Zkszg04Nv;mTyvd-pZ z_Xykh)(MPL{v}MW0l~F`@>^pAo6jT&muo@!_8u#9ve1Iu%=(PGu;22UJ6nzej={>D z$)Za2HrT=5wcz4a`OX3+h5NQQhG~|_F?oYp+#v&AOdBk2_ne3(vmkeXKev2wn)A+^0+W^n ztG0~5XyMc`e02g?n9ySK*4Y zD@=ZqniVp2O(qK3fIW%dx~uW5!3cSB-6r2Lj;O0mu?jk&zke=FvJk0oud@GYIS*^! zchNG>jdA+FHL++6b{zby`ipE#pq9{a18;rTAieRVTY%5 z+^K*v9_pf&*#m89IN$hXGE9>5pu*{*@bCQtS&1pmrg%}4Yk*sP{!IHHpdxd~|J>Cf z;fyv5jvjT;+~PXa7Jt`WiO&xJ@hIs)PhWd-)a&Ti10#3B40Wo%e=ZB=rc7L2ly>as z+!KLfCCg)GJN_i_56Hyx%~(9g39WEKZB3k`&(_VH6{q9!IwSK(}OBE33LLI4}|Fw1z2Y&DjeJUa8dM_$aEU3|I&4t}FRlrt;? z7PwXS$b8GF&;!vAIg4nS36mg+o|vqVbdz!04NL63n#9qpsG25l@FYw%xBKBmV|tcR z4cRP4taX!N6Q31v!j^Oc!Gh|Z>Wwd1?l(368r9XB^gj1wNP&2+j!7fFOm>L6URVGx zwVLOlyI*4UgODd^tC|4&hK^I7ARgms>d{?M^~NrUd~noO>;J|{xv%Um zPtw8)Sr?5RXO2a{Kj#oGeI*c1gFk9y{^*KF(HAfjdq;Y$x&CE&={1UK#u(l5(R8rn zPKAzP^dvre$_^qx;ad1kMwVEMm+UM&C{*V2J7OWNkH>nEtKex{jh1>@a77&Sc?cod za7-80Gi$H%aEh)We}SMwQ?A}o0DuS#&+fDtE=%)?6PlGxWv;pVc<9Y*PzqEGc1{fV zfI!D}&|y==S*4l{km}KTUUQVE(rHS2`6ShK2^C?JV}mJw;CEDbjGguvV_v3GWtbR4 zT8PP>&!=&>_q>?ss&%?YQACo;{3(8j9*p|3yN{O?9%M!y=yw|ETw)v!Z*z8Tr8U+0 z`1@Us!sfLK9FDMT?e{h*Ba>tLn@9n&Tc5+efQw1I_UKc$JZ!mPtp>|uFKRQ_HXU3h zy1WgFII7K&GE>N$mWA@h>&h#Jjw5MVk=QKUYMgL0P2B8>k!MNJHRg{u7&v0MfXAv+ znXb0TBpEJvOnt`%^A8Epl;t9O7Mepa)1uf;Y@`a+7%qJ-H5(~^HyGGK@jm_A6emYrXSO7|3&#fDFfWZi1piCSFBP7;B;e|9$D z4$Z>#9d&i#Q?c=L7wB zS@$i_ic-vsS9G>0l9}Fp&2dZ`gYPOduBS!qO{9->)2E2!_P`8G-|aC?=q%WsC4)?3 zY#~K-U=2TgyV?jj9u~p%BzG$RixQXMK?;Nrgx*+`y*BcJ&|7q=Y2WhXxCdX&GXJ`A z9C?w`=g2>^v$4mNtX?70Pihx2BKBOtpn4 z3k9=5nuu;~Fm%0I4Xf-N7*Aa|sBOMIQHJ5c5|(vqwBz4a=hhDsh8uWt;4!WpB^ts5 zY41?=`3}$>#kzE_aVE+Vx*svO#JW%h_?;*PDnR1HUkb8iU)X6|m%mQ&5dsFC->Tq84pv_@BTyHdB6mjM4ns$+dfx&|ztjxW^V{ zvp+T%BuTZiHL=}Miutnmzdw@4<*97^oONPTeov4sCVE1jPav|g+992m&pvP7qZKD> zYKy(P`laDBADQ2Q2}K=I*y_jG@pO{v!j&zbjxnIc<4x*WO;xgn=7$yQz%loX+pLK! z2Wlht+qWy`Ks3^e3~?zRDeOP;RsvOMYL6RtYo^^~o{TCs!o_cm^`==~6vIxNUb8QY z-l^W_k1^f|Vyv|%DPOnxT13Ws=W>IK93cR{l^7tyKdwaionV)9^zruyue1&X7vxEn ziEjZijZv{Tc{bS+VgJ$C0T6e0Hc*RusS19=#7bF$+vGi_O}%gR6Bi;H z=@FB``Y4ixewWdH5~Btuh+2cHA6Qv>be+)fTtN1AB8N)`(hnFepZb*DYB>=>6S6k-1 z(7qKix6(KpjZEDetIlWM;H7^KMHMh|YTfmS@5N^qOFT#ZhCOKmjMOu_S%(3GBp!!6 zn^-S(STjVVV+Q=Q{Gge#5P2a_6dfx_YV`BKv8kFPPt4^IzOeBScKeGap)JF@&^vdV zNz97Y;}L#4%aZS~Bc2VES$!_x|7HCcIo6c}irsvqKXx%p+g_0{Vm>;=G)ySef5na!mNDm-srGD8&%G5 z{0?n8Pe~Z)LW=i_KZPN{_5G5jw!eoFGa8#0khQUpkS$Zq;y3B;)ONJbZ|D*6QL5l< z5Nf~rGVAOfmA~QMqM!%ysX&Sa9*Tsin9H?$=E|j@j>Z!%SfE^;-z(mbbOBr8+lUj| z87$B^{YJRT+iWE2nw|lXkn*=6ilY&{2H0v(;|hPr7CGkOH^I4zAJ!gtRXxrA0Tsx zNO}vEf-Pk-4i~JJnt+7yI|E2EE26unID*tlZWVJ)n3lInFKp$~lW z(h7Ao743q^%_^+hAD{-td5E<6oq>oe1sl%d#iw=R2w$T<(?uH)WySyozWZnG)mqB*dW2pQ6r$p zS4OY``@-%$kX%cm9HMAeD(X*j6hd42_%0-ok;8hg zc-dC69C7PlgMt*+gWRRF#%Vx#!@X)NOXIfMWhrlPW56pces>M&&a?w;hG|9CU)t2C z;z0wj>7uAj|7k3or^V1>Uq?(faaxT0%Mh_siY^BbhZloFln|dT>&Xtw*rU^e&yed6 z0zYF1toEtPeqf9rq5f9~TJHiiZn^M?^zQPV87y`65&pDibW8Ov@xHPvyP^f5u8jBD z%-dDnL+`SMO<`D;g0@}V4@{_MiU%&dCSM)Aq&!^Q`DM}Vq|{; z#X>aX{Gr+bKYb2ck@bJ>#{n;5(-Dk-kv+p@*ilGw0Tz`o8$w*~_NX_{zP^Hhbc9^s z0W`5n$lH*41w%Dk)771Hl1Jzu;v;|Wv8WB2V;k793jEgxgadAqT2MQ&ds<1w_l;PG zIWeyn>&s6Ym&V`muNr9sdjX>u&I!uT0{e1g?rq+7id-Gd8VaEpzW4s8IEChaEwBu8 za6#>B{RSK{2A|&yEh*-sJ+t=RqIC9TC)*e!YE6F{VDFg$9iEEK*;8rU&p51Vcjvl1WS z8Z=_@D&o1aP^5BEa&cVgu@KPTB z<=H|LRR}FXuoG?e#5s=@T&KpE0USfo4*386kUEV7IkXe1Lz9BNm628UAC`2ctl#*#Qo1liDlb;5kqeRKfwNrr9X1$_$+#9UO1a3p9U^zE16gOIO61Rq0tyCEf?!|0BUs`N6T0ZA;%f>{A4!^z&kl3jELP0GaxLE&$nPB8Q zGNWcUAH`N%CGCzui|)y(E?eDub+ZNwvi?r0;0i9TVHJRWz-tBgSbyOR;jwH9H}xs@ z&|lTcHwqpS3`0>omfxYun6fhJlrgTeQ!9Qok2r9+jXmU$#vTQW&KP`jsL_Mvwck z@%iwV14yX4G6rBMH5_)qxITIfL0*3IMYsw(9NhHF>+F1H*Xog#z$N>o~Aardd(~a9bTVQI%G1Z^s_1ZFv z!=(=?`oJlB1;9t9jkS7}fpzvoy2?gBq)u!Ox86h^1&Yml8zo~PRUmPb0Oh`%? z)xAx5@rTpWY;vXD=00Uy{RQ7bO_UEx5+@}!O8)PMk&dHd zfbp*+HK4LKVE1w0O|wo!FS9Qk805?=L5hla^8&r@7bJ&hb4^-|NR9E?@o-;-p2|SdZE`S_b+h9TU}W=N z^p*w}r)6+(xpTzYcsD(axYp=l27{LI6b6qzr5DIQ6BO!WReKC8Z8l>#^y3NbCTF>; z6e{JW|gd5b;8RP(sbLu)qQI6_H+Rxj$Cskp0l`9jTC5pSxs;WJSbP0?Geb> zK-T#=cX`woDo@YJ2p&8B=3;XR7zO|@SXj1AsD#U&n`Zf$8A z-jDNWtpunkRd~(|JC#DP#H`6mb9N8px<&PUPwIP0RFj_EIe@dAUZdv~Fqt8;4^QYI z>7GSU9;K(4g!5E7EyP9oKI(b-q*=v9bywbB$tu&1cAcIzfJ~=!?c?-uU=t+9*|Lzt z8_`-1WZD??_7APT@Q6D0#@2&5j>Ew4cuXKTlI|~!pu->~eTK1b0f7o&YJy$NmOZiZuVf$al@)NKs6;Jyh zYtMoqfAjUZ_)>|0>I>s~L$q{7stc8P#&xC<0?MKjB(TB)Y)uIAFgmDPVxKyyk0geL!&-NEHqJA9}|g*~xZfR0r$?7d> zMO(d;{b0t|s_1jbh2)mPzI!B_2eWk0aF`S+L8B}1kkg5vlF9(Wy?}50krV$E6-4=q&`Aa2yT1EGKz(6wTxdK7ZoyeY2>j+UK7FvbBh%q0 z5OU+&ALUYk4k$5?ji}1X^|3B|p!hq8D*d%bDtS6XHnI{l7v`qegXC*u$Oo1)3}9!% zleXCjwD}xN>>^cvO#Obf2A_4{joQXtFTX)jBXf@0wSP>TImJ~EZ*b+DFC#*95n%HY zXZygf2)Ka~rpYVN`kZiBq?}MbKRJC3r%~dED;8$77%N&Kbg8AS_D>onM;khI0GH#V zNNGQqBy(P|w|gF|U5!k_u6lmNlo)bxBX++>*GVUFfcRhBM89>L;mJ#tRh2O2&XxiB z(eueQZe5|&4BDTW^9dWx=g_e4JcGI0?_+sO1wVMp6}A(^(8DwQD?_5aE{kB$rxc^XnC;-3O0vkWmd&ONp7K#h(|WzJCzX=f$RgBcNeFpuNJLPauS{Y#cgXdjXU@0Fz z<|eYZ;hGlkgVxIR7qT9RLTDRjDm$ax=0iwDqdNCa0qm9v&o`>eh=xg^%z>#nGK>OV zxcgb=R$edcM9@na&K`K0(w0Xd{_cCQS%7!0YMZ)jm^&>#h^~e5pKUtrA)Ls=T0hM# zImhA3)(5LFITWvjd=faaq5+{%YQXd^Fs0qTx$7MIfG+27HJ3L8lyzdoX~4QwGKraJ zVjgO6Tol#iTq%H&7>m~aF56=(?+j9NFD=~k`D5^ZTZB_nz(gs6335tkvs+4*E1&l-=UuY?XO#@5B>pQ5JkeHjI zDvmtYbqpGb555DjUIBrlZs|!=@L_`ljCi2yMl`g^7$d#1Vpm;4(q`7HS6x5q%(DpC|9Nu9N4!RviA$t>8%YqQ1B2U%B{j@AjJc&gmv zZ0#=%OzDTx9&5cM{E!&`Td^X0h;MmDbM0`Rzy$)O%7Ra7f=f5ZF(n& zO=1rx(!y(2+@ZqJi9BstyTh$NYlPZSf)qZ_o>;#UEI}ZVN=XqNE7_@QpHdV)YFyAC zh}~T;S=xCJ&$vc4uW)^~?N!OjZHi{+l6OpuC^d`8W;iH-gb|mjp{tHxQBlGGuBcO*qzIN)32Cu-?j8ZL zJaxj^)N!nqY56ip>H>)gz3s_M#Zg_X8E#w>A3~1#8EKYcqfWv81g`$I6TM*5zPzdV zSKd-M?EUcv=4%<{XPtrB9vYqfq~O5=&)*__G8+B~m_OysK6XkN!TXU7a86YTrsuaioaVsz?%$ZU3%|D^`=TInhoRmQzQMD`rroNy4b6 zO=ovXJA#TCuYc<*W1ZQ;1fcxZ+a;V7p7~bCWd{XGRrQH4WR?=nMlh_!AUmXA=DbRD z_riPw4t{__+tUiXogy4kdcPl#>~es01x?%h-JY1aYK+9~eayRUGj3|FW8{)JBIXUa zv}zewR24L|V&Nf4O=F*eBx0j3vmEBkf~W%D6ut$5r@BYBmM3UR8|b|{p|BM}?NSf9 zde6Mz*sgT+yD&Gj$s)=<8*LY$FKHM9ZClE&A3xcWCGFqpVT_IU8^1M2)e#lI#w!5( zIMONS7Xi3m722@=nDzs|kd>!?O0`pH=0<1Ltkx4hbKGtk9#rBC$E3A-jYu}2w#g9Z z>5x*%U^wbL3KmqTp28g-KN|lxm`g5P=QUm_Y?)bz4i1`I@WEg>4wD2&cm{+p!NhlA zI&X^TKKKe!z6R^RmBdbBdaT1}Xs`gh9ND{#ieagHzN@D2uoD6x6UPlA?)p6?y<&rH zcaN9bCvvf)X7Nq#3}hZc@REW`7apoRDo2Ub7Tp`|&Y#vRCf{@L2W`&i6~Gs{jxS0j z8g+gXmpyflt>qtolTw8-S zGI_HE3NEZ^pe}PNTP`vCoT__L?dSqG>vnF_fQ&~LC~l4x^#DjU^-s1k3bKXO)>nLP zlZ4$4cBux)ycl7K2+(nH9(c_tGSeGDukqtJ-_w!_ty$lKyPsm3m_64vr+o~VndN6-ArfPjCzk!J;X}tRve1I0Pil_j0h}Q;qqGnp*bKi)zG{GL?loN1}o?Q22PK{zo3V#?WeN zo+X_~?)-SXJcp`X%wx;3fPvnf>=!w|E+TS!D)vAR@1C=F z8GvDR-ko+(7N*$!3!$Ow*s;0^TQ2>J-3psH*a?@oa*0e)w^Y8oQ@_FoISHT9{#C=` ziB0YpzT4AM+S5#j|LgFGp4RjIu;MX!_suD=^qg)8p7t>11D~aD2=|C$Ci5%5(;g5# zMS75DDT@CEiSaodt2nZuB=%J=o0P@|HBN;IO5DG9v`>sBNTN5HLsL|Vjf0yQXS#WH zvAEw$Z_k`uxG#d4M==p^DrYC5%D2oUHe!ne1{?rIWThX}xANyNNj9FNDKr5d8&MhaOcY(zHNy}JyJ<}i*QCIq8p=OcANRwZSK}YUUfS4WB zN=GfkI+Q|W@LOKhU&@-LB(VXMvwf(b5E}CW^7nMp^z>=sHqWYciHNp>VWHJBF7F`QY$_8JV~M!qEM|yqk+Rfl%k1p<}-?ewo`2(?iz(e=)-hZO%cp! z3G3f;GQgunY8I_m09%m z*xhaFZr*AwfVC^%TUxf+%!`3g$fiJv=b_BHks&vZnZ6b=(VjRjj9H^sM$ChP- z3oe**0ulIp%=GsD`%V6=N)lCUms&WYoz4UFCRN=m!@rR}dhd6r7G7(dSD4wM*S>4S zoJaA1Lx{I5!(Y2+{UYcFi-B)U@b|8lSm%zBczd4S)W_NqQRqLue-2F8Dh@N$)1pwV zExQ^3tjqf9QH%hSaGBDM<`n-hin!BR`~l+{vv;@g&x!y3M@a&p`xeaXMKJK-+oPyoJtQ+U5#|`>@ zy$}=1xurHC;r2U0`6Q(~7qHTLy0Dg{16*;sPJ;QRwbo3Zb#TNLr}Rs58-|sAbT00B zwD?R~j;)UT7@P3ti6790PEsN|!uw`Od?8oX}f>CsneP(j5IMPT2l3r^u4H$H8H*O8dJisxM4JDP6Ca_A`#+^GB%s zITfJUb5zFmim2~{2ef0t2N$pMMcVIw2Z1iU_`8;+r6pV#a7fP9sJ#d%!u+bL2k40< zC6ZYMWI$n%XmU?+hswb+8{SohC~qc5x4aYKD-Hf{-AGogZ-(PQ7yw1k0kW!E%0oqR7k40j?)E#_IW}Cac^r(#(ilOXZs8Cvr{c{_|Bv zfsPJ;URUPMCr;e|=fDyG<9bkyR8P|XDgIUX6Bq%w>qn@Qzbm8zd;T{4asc~JK+NN2YF9J;Bph?u50*V%`6lmu@T(Z6jKf! z#kIR{)ly%sM?IOAd_gkPc8;qOIWrqGpXmRQ*=9h6;gYxxZ*V{hGdgtcyk)OZj8maN z+2j9JCilT)EJ@D9_#6TyckASIbO@ita0Jxrn->aMfE?6Ap`b$^;<%)qN$z>A`#7?@ zw+;*AG*)oO`6(^*e^88-0P6~@U|;qnO$-5ApH_j^U4~@Ov(R46JA$w31n`5qRG~;F z@kq+>H6{um>8Y}OzKA_iL^}_Jy;@E;s9r0_Kyaxnky}fhBn?0WhEQjE;2zNZoqAPL zr^GOd#A_w)tbAbp*AYp>GzGNd4R1l^OS`vfAZY*DaZp>3pWviua&LspK+Lx@#O`2l zq9;~xVIqO>_~iVW*i3=QiNv~`Q}YDsUpm^3?Z^{S6t^RuBGB%1eDLO!v^zOE|3Q(! z&9ZeZdHd%&kX;A!lMTyvWxu?csCVj>ujzC)r`~#syi9kYI4Qx1Q~E{S&x-hQCa)=g zM_9tRA(^{_TdyXKLfSx-%%8&&*#)Rb!~vJro>VEqtc%*@6nJpdxmf&FaD2(>7JeeR~(P?E|YhFpH>FwoGG7-~ewJed{=$q@9)+vw~GEIoV8Vp9&lS}{gdAb#Icq%yw$0AqZN*{y+qV9uXvxblH3CceEnVvq=qWzS)qJ$7!^e2hR28AZ>_UD^@0cV=tL zvb9+5(G0?!rz90vLNpYuh3XdX6&;rh7q>eGyk0821SWp0z5{w`a4(WKITwjkg8%*$ zBsNlhqAeZ#f%7fo%C1&HEZ`hLa&n1bW~c+I0!v}zD%?C4FrDwPAwXVPAYh}PfwaypSB1c7Z*ylLvaq_Z&hit08Rt|;TsCm7yJEG^BZ4$o zI;YHgTz(yc6`Oh!W%aoDD3aeClKpwc(} zni^b{t7N(wqv1ZzJ9{=EeK6-ltgqBmkegrT>AO2a))>Y0V)PMMm5 z_aqMKEXRfjA=#wHaPUgJ>CMWJ)B@T7jgvWEflv`x) z;bTFDi%P;m{jbRr;_O0FXB@i6@ikCa#n?18d;-l|5_f&9L3;`!tCr>|jWH`TaO+XX6j*PTg=#W(kxC0#Jz%IwFd%GgRY-9cpxSfg2_G%IH1(nT~S}1Q-WQlkHu50M<44Nj008r4v+XN#AM8Njq*qU_DXfM?8j2$~sKDe&pLd{l_V?d#zvXSgS&>#=h2YI$>JZYRVgi(I9xk? zIhZ&LrrOECvfo9cfer1gg$aZ#CMXw)l-0TitJS+jVPv5Y}|E-^4gnnEjM`xW$Ed@-C8m`JWIES!Q#hx*0msDbp8SekbgO2RqGk)o_!Y(DfO5l#u5^n?v(eRqPoxXN0 zqFM<4^>s%aw+8%>kj)55m8gsM1in}{C+RwrFs(@Gr1tUtAv5bzzA+#_fdw}+xA3xk z&C826Oz|QW<*_Uy<`X(!vD;taL2l7fYbSsQ(WHkrwToszubxebn7DHFP&gx6=Hv`t z-H(P)2#KniZ&|%WCrGu+0l-xnD+Ycv9ff{7g2gLRp$w@FH8hvzbt}*3wlT+WX@=q!BxBMSNL|O?{t~&Lfu9u5hx!-ax4STG;BB!O+dw zBigb&sp;_S^=-@WFM`q)Yt!;jv1YiYu|H7Ec4yq)uSL9Ha>TY0@t=? zrdDEe<%G3Qn57J z?GZQ%A~kC_g&}{$LabwnEc#;y98id%0P)E^J@6{FA+D#OiX(Qjd4zH@0AjxqqZs!& zQj(I`=s}0~*!hYk&8~-9)9;Z-Cut&&4`k%Kiir1RLFL0JE`bJa=Ap?Ilxp%PhioP)pl@`xMz4@d{72JvhDKWxVDXD$ z(CTf16xh-qqi|Qt#$L83x8_jR0dC}lb!ih*17E-~N+K_ScM#Xdt;Dn_gUwI@wzS^# zrTK=NV@NkO#K2JV5)_EJf&Q&C@lr$fNhwNqKpkQ(?@DfL@{;~d5m;oUR7>VDUK@Yk zIZx$^zO73p1_jl`GJ{FZ3^wPZIm7tBr}a3CEgypP^!CfuP>FIz5Z)!$%zc`AXAM+& z<6{uPdKm=89~W@Wdp21yi_fdB_XQKRch5G^@;k-{9frpCa^}5p`@V3nT|o8Aeffmf z82d-fdHUk964%J7b2+RscD<1)|PfVx2-id9+7sn{^Kab>t*!qU(ONxyL z<2_a1zmZHB|1;w30nAt>DlDmDR}tG5m=-K%rv@|z3i8h6MzUN7D=kML^t-IX<=ia+ zWslg$t`aOIM)L_uTx%RHfiFqo5;&5-ZuSd8idr6QFk2|P2J)eCT#(A;LkWCl z5mOHBiefnNO(Ja>4;%xO2Sb9QnYCSdZq3O9x_k9CQTjQ-=W+ow0loQO40{^X8jYhMM(v{{LknHEBU@s#H&*5m7w2FPnW3GCgZd@R(HTXl+|p;_ z2TR&jlU0g^fvH1~Y9GIhHQr!1MSz9j(A&(>H1qVm4iPwZ*WFI2PY2LhCYx^>S6J?7 zvL{&$BW(I^Vg4PMy>Y#QI$D;1X_93FM{6e3>ov#H1w<@A_iT`)P2@eOrN4JEQG;Y0 zMQa84Ri%U4Zfd_$F0dH$OXtHFzy!h1=`D?~b8L(ZUxA>yZi)xSP~dpiRu==RDfJ0~ z9xaEEG4AGGT_FjBaght+*2W~92=P%jerotKMLE6uJXZp(jBT!>@5-sS*zKXGTwS%T45;wCZh$Z(lKo-mx%ct~v)g&?F6O$(@K zkVvk-u%@v0?zw-r7Yd={k?~UUR##H4_3P_Hsg*=>QXFp&pI1yXr+uxOwHFdNx&exz zjc|KrA#DuJ)<0tJf+DCR6OiCyRY3NBN<*&@z0nK=<#Nv72>+dX{>!#+rK&F+I9mNh zBe$p}8F0#6fkTKKsjBBx#ry6d!0fJ*F21UWz+tg+_ZkS)JwrYcZkB6NUrub@WUXM5 z6t1Ron5JEr4#;&A*W(W2X~>4b^NE@>xt4&;FE)K-p?*X{L2xnHjhq{N+0cgJGevA^ z^1az})Kms^!eE=1wNWlWOwgZzn+m2qLq(ke?uv$z)ZJdrDcyO)D#4$&EwQBgt+Yo((q?Aw(R)#ku42CW>##AS|T zz8o`N!6BN{uH(F@9870LP3j!Nsy9EpELIVI+}}v_%FHve_er{XVotDjW#!gdP3;A(lf(2fX%e z1bf=^bE|O@7WYiPx+boERoORbXeV5F%VZtB%(mb5(Za_LKOR|2%aQ2n2KKAHI%?e} zLTP(8mmZnkU1Dd0)Y5<8P(Qb5t|H3{Z$;$4G>!I@RHTrtS@M^o@}z=JT_cFuX^Y(U z_D0NwpKs&E(ZE+(0!D(0z`JSk{wpiSB`tKLoK^)zHDklOKAKUVMjwHPl*~$V>NUaz4|R&;Ziq7$#rra zNhCM;lh4`1LTpt2Q8AY4Ge3pN>IPsY+nfL6Rx`%7sE}O6Jy#m)n3@Fh+3?kmkBjQU zjr0vvPX~nS0pvLFo&$PpEuGMR&eI{YOqHUJ!_7j*tx}p-ynweVekxqqPU*+eSQ5md zZoxeXc(t+92X_xsxT2F1WZ;9_Y&*{6XCh|>zk%MkynIhv7<(I*Bg_=a=)v6 z060Qyg}}X4#ul4mmx6sypL(1Ga>c+n%BQlU`PY=!v6^U`T1|!qr7B@+_^lHY^LKn$ zxQr70-sV3Gonkxui_(7i9GFj3M^^oD0SIH&k?Fw%V6Iib_rb^!U_q;(a+^k)>XOda ztHD}EWbL3(eqda)^aE5S(o0t2v?#AmK$XTFvNI0;jHhaOLGg=T1#fYo;Ag+Rk zTPY&9nz@!5X;dAeoTqKet>z}@(t7g*6j7S@=88MZ&E&bRmMVAlqfb2G+Zb!&R!X)t z7{mB&6S)8S3N%mb!$v<1#lJr2m5OZ?p_$OpB5^`~<8R$W#TR&B3;TZ%q~3$YKY)Hl z{|+0VkVxzQ1eiI;Q4#nQI;o*)Ss`LfWTy0UR!N^_+11xVykC{H%l@K&aB)0o%T`BA z4PiUjoEr720ld#XIkR3zg_4VLTzB3s!0RB5G!>??cd2`Eo30PB>=yUHHg2zA<_cBD z-@}=x&?6(>sPKISp{M}X*!3M1CzRI^`r8#?{nM>iJtQ0*c~myw84wC8%_P33>#o?q z%+q6h8qR5*#=D#m?MgCd$S^yAzbdu7kIpxq?^0PDFT8>aS|szLoSXtY%GtScC@)iD7pCuQ8d4;liLp#pRd&yJ6e^fWhN z7ee!FOxS9fX%mgoaXo8StlJ3Sb5{TRL9oPD4gt|28lDO@$jNIT8~zSK0-2VQ`e*!N z!Z!Ubf&hO`6H`63p~dUp!Nt9t2{-5v>`VHL)gTqJcpa8&EtZg#l+!S#hj#@(=40BxS1VE!7hGsoGhrPlm^N=~l$z4L&}lP1Bd#6L}#u6g@;O zt#eQu{&I8}pXc>5Jz#~`MNs_mUh#f@`_-56pMfZAso`(7Y@h!QYW@~jnd7e=@G*aq zpG^ZT@0MWVVdn?Bf{G%*jsWmUu+%7gANR%#&jMkZw2&&NXK~=uftJxj)78lux?2wS z?n`(PD~L)?A4ShXG-tIc?Lf})@<7!t-cs)HLiK*H-XorbE_hVhb%1CgKbc;B@s}x=Ki7C`A@X?>-<=e6ODKRG?kA zOU|o`L@@Xq)Fe&80L5uFf_ef6Gyq z$@Ub)9vxh2qz@k?TRMQIl!;M+NGP%}2A)!#$K?3#zpDNUb(SizQ{2$ReSr)Q3=yq^ z7_3`yB4e*IC36%KFRWk`3;2Cm!6ao8+J-I$^c3*o&A@=lQ z)eM5pF@#N2Gj?NTP@Er0aX1|YIY*R8b&g;BM|ysK2sW2O>XS39z^1~AR)gZneU_z~ zM-pqJ_dnps``U)K-Vm~%6&SBf0aoRq{Cvod*|SP~la^<<7CU;jph_Zs&_Or0rFCX~ zTk$2j{Us#(TFuK(m0z$RK4n}{0_R?$S*C^Vg^v9Pl zMX`C?V@B#B9Ket4b&g1H6uq_`CsmC99>mplX=k)nCeZia2j)cv3zQZ_8ckG`|V6CVbZfisq*--xCso_kFaNyo2YtKNz>KPVq|b)m zh(wn_E=-NWL&$mhJq+Sn-y{?b9JEo(_+*D57_ z3|~XN)xYWH2_N3!vA;(DHy?KR;?Iv!D}#?mxI*yhz%L~11djQKgu*})qY*BY>qVsPTFxO{6(eJ=;zz|nu`Adl_| zB9|aHrFr;k(J7dajK*T73H;Hpu^`)IL?uK9;B`NS*i#DBzu7R&P6bi0B%kRzlPGQhN|xI{fyk$#MAEzoL5T!c2PImhT5 zMp*k<`Cc2Rp<_c&Y9Dq3I#`|O|EjmP#ItJzTjeIH#Boi{qhQzZN_U1GCTx|?_(Pi; z{c;(M98!*WJAHdFno6-EYqlBHrmM@*3mJB^O|H-W8|GBOy}Q6*Wj>HUOMA8*NSn=? zj)s~?Tl1*|gGZax9VHAG9Bsx`l7!YPYnC9Ur*-tn5>wG(wa`l%O~}VxlhjRz%S?#Rsz;}+ z5i;KvQ`9*L4}X!!8Woea^lKg2Q{;w#RX+x6Od*bKNFJ8ve-SHHtTdk)C(N50xH#lyAny2?ELyT;?**s`e zeItWInF1XIxnTBg`0&6r8v2Uro-Q8xruE(Bs7nPo@SJ=^rljiSb~@Ko*RQy+%=*LL z%`jHrH}U#p8F8Qr)5nclh&&YgZ(CGhZSgD3w^@O^`mb+@0B|t%5JY!k3ul74(3rL&48NHo zF3!rld4H(-TAR%gg42_s8D0-lD%dDQV4&7cQNkGU$#+P_yDyr7&>+p?+}U#^iH5kj z1cQ$1&ywwRnB`_mpOs?*`L0N1D<4(^>gP3$1{T&+(Ov7&loL*DDMe<~$`OQVp6-11 zlqMe!d27hQv?rnxoRsq|Ey3F*`LCQP(AK%ny$=?k zcNJ49R<)9FvK#>c(D7@?H-?NMt%lm)FqZ4r+DgVR`3 z27MVY_)I?iDH$-n%!-RO$0VI}1Wreeelx!$hsI++DPSfZN_QjM{?axsJOkl=t&%cI1asY8(-ZAtDLV()$^5l1E)MPBoggq<^iAz zN@!ba>VR@RM)Fpd4GD97C~SaeUCEXA<}SQ?Nk9gb*ccf9F?V7=PO7-BSnc}i-cQV> z1r!H+82+<(i+Y_|h*g^^T)mA?Fvc}%;g-`)Ww>7LVWL)34n0!wjyuwR7@(B!tJS9E z_gh^_CoZw+N3pa5NJa)S7vxDyV~U|j6I3envagK(Aoj%m&!tIsK%)fj=Eutaok@G^ zDJTaQVm|Sx;7`d=n^$9yC*mt|Q_ZPu(Kut+HRR-G%SG6CC=plZ2}+r#aML|f#yj)H z)=}4$TD|Yz54Vk|?lN{V>#$vQihi%l>d{g(d8ex7pHvCPaV#bNrh{l<|GQ$<*YFG- zHYC2LOFET=;hNK4lp#)C3$8=bPdHn*%^?kvYJ%5VMMtsZEyQC~T-AGU1iQiFpl`F8B zmdvx_Ao8#^M-3gf|E2ftqep+*tG6xQ`jJefOb?d^6c6y!up!YSSxxFJV2t+130xch zhN3S^u(cb@ykW2^h0%yx4&X5I!^@VQg(V3R}3qlx8^IY<9 z`Q@Q+MFVCrEs5PuBxd073|aCz=!5-WCl`6LP?fJJg6nRjd3UibR+?*O^?n} zg9!^k7XmY=b2ByVIMaY_5?ue1 zO`NL#?pt zZp)W2YiFIkW>+ciF`c=_#y4K9ab{tjS9)K5n5jHS)m+7rNkM5QN(lJfln7(XDn^uec@GE+!eTa z@GYRKSh)#{k8T1)Q90i1kA>*fRFNj%=^b`r&hLrxeNi^v&pPN{6#%I}E^se`i)Of6 zz&BFqWx+VP3j!QaI@Y*W6d1@W`ueNVORNM{dvVhJL8qH0gzaTQhj)Z~4%smaqpTc1 zl1}a1s{R=ueDb?FDW9Op*~jE|Z7|ja25(_zmr2+0q1bgHc40ouYJTcsz$&6x4fC`; zM2P8#+A98d=r{T&s!|W^r?Rve@mxD!>S-4goFMJg%{=n)bwv=jPo;r8G;JiMy!e}u zBTcokS&?%wUmlo(@V9VU2Ln&N_L*B4Jp^orp(g5^PY8h?PGKiUn1uQ`!X}di2EF(k z+qmd(EdPPQ7wg$B=a@A&uFtb_?0tu-TXwL7;QL$+->WWuu!XDyVV1T~&d)hscA6G4 zS{o7{81PiR3ZR4xMM}K8{Q(7ef=GQb>8;CmW`1;Z{rP>! zSb%nn%__%Y9jtI5cEXQ=^tZAAkBS!6__1x_7spk|%UDq$q4+rYR9NT|kP@Xm!bc3J@y)ZZ_n5qF#;|Fjd(mM0RNVh0#Py7|htmt_j2< z(W>t9f&hE@20aQbFX89(+45i8#`^-e(wCR z%G*9p2dSU^A<6i*XUL%p5Gv7jY7Kn*e&Eoic`YsSOd|FJ4eERwciHomkibBZM@PP* zg0{`L1fAyElIGBJSg9jD4uQpV#Xft2wI3%l)VDRix~7L8X&t*6GH9r2#;=w8EA^-Zf15AzaJnligTXgxE@zDF zrV)?pH)rLO4a{I7KYV9ufoPXZ?CSo#Hx9L-Q-dCo7g~=w=!mS30K*c+=zJy+H*MV4 z)wo_j0wE*-$U?|@Y>}x%vctO{n;&s`P&fOU1n1IHAdjk)X=qBs21n#*zW?cJ@G}GC ziOB8dD92rLoE8i`H!&^;P6Op8giGO$6rC2I-wycwESH@hN(R^+|NHMxvj=MY(+Ulg zyN&0)|BGHd_<^b1tQtOTuaEIYAZv%4g(5sVAb^9w0{e*+oN`YA;`nzwaP-i(MkQ;I z?U>#IlH3>>@-!Sytx2q2rE=(j#{5C=k$|LEXBxHMZj2RIW9nO*H=Nv5h(eraE@FqF znpQ?3+2U>0YQXUtIE`ZnPLE4~1qm|Fv~Y=h=3bt~#jk6C57}EmvGHo2TDP@lEd?RB zfr>teGD9O!RB|c9ah7br&ewedJ4|;H{Y0rCnyD?e@_QBvfcK4Bhml;|dc!ROo6kv) zgz_YWW2^&G#YWD;)ITMZBv(c>t-2y2m~nzKzyH&1MH}i6^_0oo- z(m&}X{%uFlfx-6}Z7gxd%GCr7(Q{I^bmZ8-OX|t$8VhEN+OB|-`*~q~P04H;HqAwa zD&bj$PkAz8{0&|U#AdXs6KonaVGGOvAX;FS7@$YcRX%yVo~hH6S@0uZ4DyTPBsIF; ztp>BBt{cAE(_Nb*4ySVk@9Q%65DfYL|NcJF3A(Zf@K`P6h7MAHUc!SijqY$wXl-W` z<+YN|W3aW$aGKRRn*nj}9S7JoYY+GdS_~ZQNRFn!_oTL}SXr*tycFw}{tk}RRNl4T&5_GeMQkL@E62X6U zXKy*Tzb7(Sb`Se~E~K`m`HsGycKft(2YK-iHf;ogA^i1F=XSv-K?Xe_sSp^E^=L&oF$CR^uaHgRv{laFGkTSnIpi?KOT*}>F_o3 zU21fD$qpU(^A-3{?2v+K`{@;X2`A-MD`{m7uBe4m`jQaKhN z2!HX^y~=M7X=`CmSU!}m__^;jIVqV)`~4l~oDm*V^2r3YI;OeTEQAIak_mYlt_KW5 zZ3#E3Ps8u|sgsnlw*yOffqKhlEWX1Rr(+;~txzIE7aon0P!Oyd^=6LHLkCefcbGPi zeHwFk_R0fspL751!=S{FPpn8Yw2o3;Ntl8U$l@y!b?=h-(dnjl(ZgcZ9d5910TT8& z4+?)1OiH65s+`AVr{h+Hra?X&HAEe@4M2d$=1^!lO~{jJvS8WU2rt;M39f$hn-L9F z^0J)w-1Q34o4BFgCK~h(U=s_mK1i#@xb@&?rXO&ffcteqXJaJekS~)u64NTEO1@@X zSt`cOl44&dy5jrYd}4Z+voOX=X<`AT0Tro7EMU!GU7plLw4=f={QZvh0yI!ea(qD> z7yTZ2?M`;F%%bZq0_b$FC&)5uJpIilm_>rSf=2JTk*f z8g370WYJ4}`#9>tDOR%q5nKP)0oiJ6x*psRb;26|%#EB)Sf}o4>Y6B5QV%?;wSKl| zvWHdg&~X-hW=gGdN%|oP}Z;gh;-V3-XNqtk8?-pa0gllPcN-?(cQfx1T?@F=c zE1F?aQOwoaBmvm>BMhT^-(k0iv2B6Sp^=C1Ad9CxoKyfXu3%$^1yI37NaLP#;pNXa z(v#Qdke)hS^1>pJw`mzUlG5phMLCKwvYKEKMTXm5L7S#h4;WNItz1rx-!=;B` zSoDo>QqESx7)*td`!o*tc;6u+)BT9mnb= zSZ#~*Nk(*BDx!;^!tDdJ!sO9K(Xa6CBNg<;J!au@?JXdg|BV!?ig?4od3=ILVAO1WZ+Hb*3%YApisItB%ppC6r&Ffw)Sf6Z`^oNLh0*lHV#jEK zS<#!idLVT-zY@J)sINw#c$jkx4wQHx4R;y0I{>ImE_tU1@v(*xpoya#fvMUszK5~+ z*WdC6N0cFcgjY2*P^&{$skrsS)@MTc`(8Cw#88fK`_M6qU+qq!7?8%9j;%fqXj(EOD_PTwL8rbO zvP$%n$P{K_Q(qn~1y%lx^)O+%bTxi}oT+>n2jQbK40qMWncrxW1p@GPu~W=^%%VSf zaiN@5PmBij|Jo&{rimD(h@|fdbj&z?0Y9?X>1vCvxuy*wQLO7>; z45VFtC#YTh0^B8lb^1C;eN_7{-KN9{O?Xv9Q=ykC| z2i?~2-^emVPxX(y{_y4gI)eJ3oiv?>pz~26rK~BQpE%3$;kxmEa}rdj-p2zF=^M@b{m7NjPR>M=RH)H&z z!V_>U<1C8F(ZOr-c;Oq{V zHu^y))0Gg<5w8sXmHC2rxyXYTrhP`1Jc6r8V%v@WBXHv?6?~@(})$p@yG;lH_I&)6t_^ES~ zGC#xmTSwnNGFFsP6H}in!f05_jdvpF*QiFmeiL`(q-~2!MnoF0GLFg00kQ+a#Sb<` zfQPL1yQFBVP>Zp$gRifEJmM18aF5a)1}2VyyH7Oy$A0HyHrXXXx6KyYAJ1@);#CZ) zOTGNp7ia@J!Co>w{#dRMPIAATj%{^#qkXTy{O43x+!icoL{J%XRouGR>O*PkOZvP>PqIyNm^j8xCIGGrp-jK43|ni zL5C9ET)XG{V20N&xzI7s8=d^CmK_I5*V=y8ByT>J*Vem*Rn8i3d^n8#4X+4etU0l- zyj9}Yq8iGkas?NeXiv%2~N#B?Cvy z<*sMCxiY-dP6lI#kzE{R132k*JRdGqAsWOn?RLzDK>#Ma{fyZiIqhNQ&;4;6tqSlz z>WQ+(=Jn;NO{&`WqBNeO+P(TYGU=@1`LBs4bz+gD8l_v*2_kXPK|(AD(togYtcCLe zg7evq$!eiZpMGrk+2yc^X8$tk#)$SA&CTT|9U8liEf04!6H^Jdb+oSd1}lrUx(4$| zFD7Dq@Soz3!nUoE$O)>=mtX&7W2}}Al)bqsl#y2Vlq4si*X6`k_sG9vW+$u4(^N~} z`v@NX!W;UFlh47D?~maG7!G^!Hr3uicmR2i4Q5%=h?mqWez)^RaBJz08M4SwvXP6e z&BVe#KerU$;e}EyOT;`832n0LgwxY$l@`h|^na%wu_om?_P?cBC|~2(TbB zdYUdAqm7sjYxUc7zhSa?G^uWOFn}O^T)@@s$ax#%j4)a-D`A#ETmjf~QSL*+djG^( z#Bp3Ewk$gdrzbC5W7ILdMWgnzNftecpyR$)_>Ej~JL7E@_J4Wl@Ux6h1zzB8@1G7epsNG*Bj%xZJ) zYfrbF)A-_rQ`U=U`FP~mXN5Vy1F`>e)i2RKjd7>ypd=O|CtQ;{uwdhj=9Ra~?Wg zuCdBr1XnZq&t~=ypc8?PPJZjJyPYxZt8OoOz1@c$ z1tAMdg7#zZVEH=YvyN*&P)YFJ{I8|ov5lS;`T9T+v<3fhZRlkc42ZC>m9?DY3P1a| z+d<;XI|ND&vd16U2*J>n1B@Vogb#<#;_qnyLkXZTZ*%Ta6*nP=LRNI2d)VE~N`RtFIk=#j5V$I})2VoL!hDW$Z<7Hzn1Nxx12dL86vCf13(caBk^+fO^)F7yk?pm5Cs|3$PlQNph+|9t$+4>_iV|?G zxCQY)1#KYPXbl{&{Z{$;U?d2c8GzbsF0k@m}&GU+6c(M^PNpf+3I9%yPz+u;3 zE05z(Rq&HX7AQSqU#&pu=kh0>5daWuD_iywl;f@|y=8YsD{}`kb7CKL$SG~t<5ygK zgvb$vkJ9HopE>w=Q+!gv6XPTEaoQpqM1@UsMV&$Fv$E|~-H;79K;=!W?G8)W2&k|t zSor4m5pP=|{&~uK$k(O))MSJHyytu%L3=^n-LS}%XS5gij){ztu7xs5+P&m3&df)+ zG!FP+aPn}b;dm4Kc;51%izOG|oEWug@&%v!{WJkmuwZaT?3bqQ0)eEXXGprOKM*pj zHQ}kIqITShEXS)C0j@fa3=~RvUcxkJhcz(a2OM->XwcIjqEo3IN6`4_Tc(rP-X6#9 z=evGCz^20TIe24e!jX70HCAT|_v<~t>5UY=Ed$|}?*`q+>#+$Z(M1EdWL)vfxU^ib|v~xYb0q@>v(@c;iO2+_iTb*Gti4!n@mxs*-@9$G+^NmrC97kB1Ey z(-%0CosAjLg|(P!XIP)U=FfXnwp-)6)(op5tjpuji{oz2EERJa0}+)*YqZY->g$3Hyv?JE7T1tYNc5A2v%Tn$rAzToz4S zLDV|BOjvngP;#RDh|{8o#Yt(g1E(K`(FVo5Tzh|JaN0#d)mz)HKg&dOl^b6zZD+X( zxAk&ckDznC$q>b@pH7zTY}AmdiVtX08Ly3wB>+7@!oO57)VWVj_&Jqv$Vk`lw#X~v z*(ZsyLZKp)O;cVm?0rkaQ_H(JND4ruueM6v!=(va-}UU)z=%EnVOSYj*=X75p?e_S zC?-(Z8ZKT4yX+&dLIwzy2bu;(y|ZVTrVTHOr6b&UJEz*8xxp{6(~fS9 zPo-ibz@0sAMPJN~IKIP2xOLx6&QE1~)cQ!@kJ7JRj{~~o?|fYIPw+#|W@EH$uS_!2 ziSt@)G`k@B_paCVJQ?cB=+sm0Qt;CRR;C2|yPy%T7Z8)Fq10v>m7LVn+@SxYchq=9 zEh6l8nzuKDCWj1;AtFl$hoQhFir)ohk$E@%SjP<8nPx2XHw%l+V$Jlg*rP6Vp5!C9 zwsm1f%Au#kF?3gFeK3db7RyF{-fzFKZWs*~%IA67u-E0_T}(%x{j85{dNXM|YsV`z z%j>}v1q0c~BZ%bxuD0IsYa_`df$D2VF`L0cuzpcBgG-Abq_fPLGc|GIT&YsROVCNg zuFuKvW!`R+&5SZ(6MIetwMSwP^Z>ibmwvX0>q61;?0*K%@hGm&CRZ)lgWX!Mz`Z3P zazuJ;XlI!H-~@+o&!KeXxIU$q@4xLyeOJUOIep~VD=+~)k}cSWGls|1#Ri4PI0GZd z=(D^ouge+-e7pZM+?)(jTiw9TkK6n z;>B=J$3JmFdkJpSEDxUfEaW5y7?0I3IfkJh{&qh7|J}TY9TL00=Eu^yAywBS9sjgO z21s%6!j{vcPpBO^h;O>R1nPW;_;>R81UV{oSMG&a6FVGm7m)4`;qNwn;kRp(l?{u=bpl|}52TC16EI$?_IZD0 zAH^8>Zb*vG>l!5VaqgL&MUWd@Eynm_(nt3{QkRr8{d*{gmar0zJ-u%08G#1g7yrwcd1PzCi@2K?Ha+*32oNoNM%Qk+qMp3Oa#uX}5mfZs+x0F;=BSlhnbu=n>n{IZ!%}i`3vyb42nVlE&|2$@yh=vcYBNTgKO%)uHk{mc5Inb7 zBTcKL@YtuVO>3Ng-mE9wN4BTDY|ft3$j=V5T?zc3NF9dxAx}<%MtO!zQ9*8?0Xj8o z4tcfRcJ=wAR|qXFIgTWPsPW=Yo;6f$3HoS4O;^r=k241mtG=`@i!t`IV!3v z^Vm=;D^W@iO3ggm_wfnmi<&+#N6Oku@a04BPYE4Cd~(A!noK&`QX+_{P;7YB&r+oU z(4I0Qo8fa1Ab*ZSR7??)1vaNJ`2G#m24M@0H4k#sjNlduqLqkAo;~14MU79?^;PmtEUjMN zuDji(?;k%zOBVd>^9Sl z9!cdQf@Ep8QGbsa;lMwyF$x|XvNLE@d{!I9KF94Eq%th}wsqLulHrAs?a@QHhRx2a z?K;#-^CEI@uYZ-c*k~Yrwe-M*CPj_@T#v6H`FAEo(c26Yu&jLj9>%8UXio8cjyB>H zugk`Ec-HwsTIc654>X<4&DL>`Ky|6qb;}L&ffLKWtKxlUxz8_<$Pg{MRQ2jO}&qe z$x?M6_v3Jk58IRBG250M^@Fq~=UqL1Hl}|vn54|o_pyg?(J+TQ zs*S<-0|`JI4*x&{UUoj=m{0AOLI4#MW8r8WBmNX~eFT?L3PEL=T`L3Cd|9xse`iO@ z&FMgXBm{US7VPO&PbZSTW%g7XPlr|CHs=#)r58QK)&o70WL&* zIqT7eaQ}~k9YSr-OEWPtc*e0saF@Psv6jFw8b~JK2&l9iZ2K4vA{<)$p?QlEZN9NU zv1QRg_m(*)rx|i)2(Ke2wcsjaQbI{yfC$LhGEJP;n>dZKIYNoR6DT0|Y4gZdS7Z+q zMeR9b5zuRVR^3Jnc#2q@7-dV{<@xO?UB&q83>XmIM=|;|Ebbq^@Wp3-7xEe46D?Xo zD<%8#ztS1zno1h!3Qs%<%0#ptW3#Il0Kx{XTFM#-t+mZ?n7Fnss z{6&oo39s3Yv`kf&CAav5()O90zGiAySy4KR#MjzmqwSb>ra@#@J5cLGb6QWdJ--nh zP<}1SayWv=J4>kY#!0Owk7PHrX2*GLFVZIY4u*hZxW^+h(6dyl|Nc-G7}Wyxme)qT z8=ySaxu`#qI;~fem^Bkbk?qTQpK)3_aH*c|2i#VPZ^e9Nvhq7LJw}Sf zRN}W@`(&wuuAsRL+CP7B$an7V{_)6lz}`xXZn{(5N2HYsY5lwLbZ!CGL~53RA^+Jb zr(hn?-C{{lC5@F$@el=NBI1z2jSYcA_fSa0SsVI~besRISS&^Lw-0!bFguH`m!o51 z-M`_qRnTaWSkw0=PY@{H{=dajKsA<(IvWo|8NdTqNma6QHi}5k9 z%R2R2j-FNN{o8ZSVDGbHyEYshk}d&VA4T!G)9smTeE;b)mEJ9s67Q!lKWWvhbwgw5FUYl(Zel>&1ZrZ%{vq)ic&{E^A@xEx% zeGUu(XusEEAS^8zE;w88&{CnA&KR$4g%KDHU+>+lj!F-hK4wHR;wDx*fSB=(g67)= zz>&vP52yzzj+VHF)vlf^7$1QUB_?(HCj}gVuxap(s4B5F6xjDzTcZM`_HmTg;UcvK zHy-}Z=Ab9$#PLkJFD&znnp|Koj_ed?MZs|n75GG1T!)leVQLEL82@?UX>&c@7`@v3s`bIBk@v_c2yGTB5&?&&5n?@W;boF+W-~5l zz^;vJ^`R}6&B0Wb160**%~zU*MAqm%ukz8Ni6=mY$^q@Jwlv7@?hHSuJH_^h^t&J< zbO9n}>IGeAZWbmr-e8Mgzm+sQr(8g><{*FE9(22SS>%BrN{lV+>GJe4cK-s*lcDS8 zemzG&`Mq!tJlDKIGt^BEvIJqK=1f~Wt$iLP`!yVpji{bFp`vEcoJn94GCG7I_1k!6 zt=vUCcI|QM(5_z15M*3}if_D1LiOU&%ij1Gmh%p|4TYyys^sA&qXdrfnKI9jUfX+| zSoQ&UUDtc_My2LP6XQ<5P=D5RIvZ`osJTQLmJlTie`h)|5|LE%U`jc(;!x^4H& z{>wdvX2`^w$S-lVI9CB+?3^LTQcISB>QChNns%7NG%u>V^Kc(wAZR7yitJa25N5nm zqSA{y(?F3Ih96fJMp%Sr%aQI~m>BD` zpqG4?@UMBa7)K8jPX?|M?DZ;fR+GTcsYu0b(VJUJL-jvQT^nvU=B3bJJ}8cYq2}Pt zGuG)M5wg=;W`YDZKX#y}02|?Rq7#u5mRUnshTZxg zrXF;&q!)r2$N}zb{_PpRo>r$-7oUI#Ipt#kuBFO#aR&j~pyFqQmzd;SiNk*-d&VwM zK>;_xVF*3H#~U#CoNy#{u#DWo0&JdU2IRQL7M#GcEq&I7Xm1QyhlSsFrY$%B4}sTA z4k%i!C~!P3io^-vZrOGv4`r=yIKk*H#9=;)NOu&+_xgd0_0%gQ%lP8Z&+kW(*qc-* z+E=hw=UWto{Q)xcz-7S3tlhCjh5$l zyQ1;wJF()7J4{DluzB>K`XNm_a0)0B2wTI%KlS%9VH9Gc3*nqMFL07GP&j$huf!dk zcxm#quP-nn{?xlMRuM}A!9_=H|BD27YuL#U^G0UkqYBXR`P#y}GhA^^@uR%8!R0X1 z_Qy+sI>e9Ifhb%6MGrr~4VE+9!b%=2vR|U&&SPp{v%kiw?y=Q>i_)IUA{CN!t@2-b zZLD1CD)e~Y;YBvT0MJ83lE7f>UVlbW21b<5a*+?7A6cyHfw)g^2_~eB9#ly?f}~nXqqd6EOT+L4Qb3j9y*@_OsqBY83!3 z)l%oycQY|dZw)aVMs%T&4X!BYV8r5TqA6?Oc~WSI+@_-%VY!l}ItPQY(hlCA1yR{^ zknn8Xl}xXtQYYN5<`?G8uED+`BSS>_kP@=FOqamX8?6sR00WpdQjqLn{-!-#cu(Y6 zx%|G?r?F_^(C*#V@Sh){Gxs}u$hQu3QCNhGr>a3Ih`_!}Q09O|YMT9I4@{MGYbRk~ zu}NW+@z?t%n^sM=M)h5Yr$3P!{B-~oo!cbA7Ti!fz}8JZmWnxAc*_lXA5!q89G}; zIAkjJd-BYQ1MY$^D|sHoOjc;GsJ3(uRc?symm zbPCts>Y=2AS|Ueg7u1svF`*H2I?z4_C(KH#G-+JOR9<}kf15SzjHqo$?U>V3f4(CW zZqSr6qUbq4w|~lF6Db_-Ls^y(A-gW(mEJ{|9CUVV?gSs$;^C0!=9{NdN5fMmrO12b z-;EyeS@5qJS@cwhd6_m*m~+U`k2IUb08a(I5+D{#|W$#z~IjGEn7oXUPA&tGD{0h^)>*j zR{nJ+{A_p3lKDBIuG)|V2eYz%INt0DG=++=bDpU5%5si&W`UEH;9nx)WiQWQ<1G5v zvfWKvL987Js27KGncQ#28?@&s@~E;ep*!hO9UgtHBlrr~>kTu(OM=;q>88Z}H*=;% zTdtIC`&xKYv&<6m#KaOhN!v4b;tHjMqXTP{wE%ZQF9O!nW&+xb<&-7Vvl#MS&hJ91L;&|JYx}%W1ls zN$6`!A~1Z*j#joe3*$4REM9|p1Z4B6pVsI!rmS3DoaASXRwgHbNG=|6f|Yx_3qK2M zY8=w<4Zb?7wn;iasUIv+%)<599@=ri@QQ`wKshM|DugVmT~X*Pb&$YKRpWX@%#bw{ z7Jhb9#bYeY>oh0bYgMge`zWAxrZpWfR2*B@o z3rF+u1d|uU^N>BTs7@qI6DJ-b-@LotOaJkt5XqT3h+J!-DXl@wJF~2s1E#Vi=HcO`!WtX7rt0Xth)B~a;^lJw$GG=qRj+Z`WML-d^Qw&G+n}c{(%cm%9?wQJr5q+?8Xsa zV*Ma@HD6Lnp%$7}OUSXz#XTp9C}*SmS?iNA?>DN?wHWeP;wM)C>96$f1X_yg{L!ww zocl!8q;M}SC};1DF~)BFmj>?Ch5hzeEAe6!B=s?Vml@9k3geACM3Zsnx zOcoUMd7v^}blGPfn^k?E8iqdOe>~c)V?ZuoFV`3N{0Kuou~^BjPeDzo)dRZu`R+aasY>qS7f*+(0Vn|A6$#J%|1;C_J5Q z4Z4w2f-M7IE$nXJ0Z?1mH;SiZgWopt!*djV5ckkLy#5Ad=iX4mP#~W3F}QLebEKg> z-*)%k8VRPIWXKtEVCPVpOdGB={`Brjf+hSOxk`oBKQ0`@B6Wg9+K^=wvKQww0&f0b z44iMW)DkA{{D}b%WhU^*xSjGQza3c=5q`=|lGvIECS2(|{ZodnddDPg5`RNk0a_aI z%EJ%=wrMOOnO#_oa#_Y->KqznwI+e@kr7h84`%vTbVE0@^D`;n&;I_!QYjTKO|NTH0qH5U8Gh@w62r- z80Xp@HKIXHx#4TH)rPiAoflIjvQB`|ub?|(yxN4+<@0G4eCNq-e=pDf-|9xQNVkV( zO7!CvIcqbXynvqYgrIL3c_ykdgZoo`-s6`M_+U^z>g2}u>L;>af$ya)fXD6oIf%46 zyUTgrK8eAxXpijhzGb#L23zoiZA|(+E=Xe-c$tT&)OBfo4m-lwfJL=XZ=B_OPUpg&^)|y+OMl zY|O<#F;#2sw>U(?A%k;!mFTrm8d!Ymq!t7~m=8+FWm64<{uGwbhGH3EwEet&I5As=@+)WkfhpS#s(C+r zE`25jE%|ui!RQ+wdtShDRT#3d-cD!)z$>syV33t$dpRnSz2N}Buu+&l+I506p0&Q~ zo;&PC`B&HLB+xaf!UP0UWSW(|gieQT_9oA`d9aSsBe6DlY!U6T%$D0|zt5+#3ZGO#wF|7u(o z9v2A9c5lc1R=PJj+1R7LLo>J(1GG}(?b}v0s;xb;#M~_*>XZqY!xK$Y#xM%hpZfM+ z3iv2ADEd3ZF~QWA-V)^Xx<%y5d5MXYD`|glm0V8Sh%q;kvGzT@$^J4tc~6@7)LDcn zi5@Fz??4)fWvk)xa(qbY2V6=qK=npL!;`<(WWiW@wep>U+|0IhiUXY=s%8)fQ9PY& z!qp_^*3Ohy=xnx(7qh&_!$^>DALqMnjNT;}e8|SzZeIa2O-qc4MV}E&Ox`$@OT}XX zv@|*4l2e>`zg6#Xe&g+=(=S1$ zpreHGHBW!-oX(LMijQ-tI}n+1p)8&&3D_jlY@raFI3)3`@1vWFm=6<>z#9zAP$ble z#{i(G-=agGY73fSc&B%_sQD?sooygsR4@{dkCYlS;x|%d{HmjX@;s!1o_bvWXHUC8 zYZB6>nNm3YByc$`s%yyt#n@*IBkcfdk$*Hn;a-qmqK3a|Sa_7;L8fL={iARtUwvjE zJkXuzE+tz*034lOqQ^7P1AXqyfR>7s+O}^8TB*5XrroU~uY>16ls^OSg|A~lDlEPO zIyp}GSc_ytXXYBL5FT!P3^a%r5b-h0Tjlb>`#@Qr^hjc%pZlBU8>J z%9X}m;SSZv52gkneXl?t>EyN#3_?#{84E~CSyH9z1A`r~ZlM*TyP)X}*>})KSICxb z2J6IoNt?SR-h13`BF4sjee*Duv!FJzb-IR_ea;fn?SY0sDHFhUu&Y2hD)}20ePl0bZ&KzgF)f z^Un^Z^3d~n_TgdrX-74(@4f0aZk#=e_l<#oHu-4EQZoAI@#~Ax#meWM!Zkh_+4@t? zooJSzNn{*x3$pXJ|54?DUJW}{c%*7!|~)ns-Bd~ZmqRCZB8XF z`3h^QkN~q=s(a}Jqp_Z?N$Zm!MGYsy^*O(>ha>4R||i zdeW``8AVqfS;U_}TJ*}BS-Vc0SJ0GdbMBV*CX^0W9#>c|t#SZo)!X3EXu_qly@6nI zgu8O2meII=F{y<=DIGX6{6-nv-8FBvgX057u>^P4n5@tTy1vkLPRpRzO%?6-)8{f( z!z{dQkP5SZ6%4r+Kr<*@7vJ7EQ!C&3-q?EO)}-^)ewHnL7fe?i))xo%<`(tfYW~=V zyT2A*aDeL`8HYWi@rAu1;6o*LMyCIp?PDKUGq?P2zf-~w`#rmVi-)e{sNt9q-!eJnXDUfz>MgljEdL-6nDoSEbu<1vtN# zdgYYLOc|T`c~bDgUyj(cvTLR-38lSoM^iOJc3gj{^1F3b<3Oo$o-nNVy%1d`&c2~1%$4+SA zp|${SB!%^*R$O_JhQ$De#;DW~)%f7(-ReWz^0WuoL>ZCkI?&_xLx6_z0BYbN#d)9u zO~7r!?Xzv^I`PiAfbtFagEKPu_CPaL=1R`8vkwK}>rq=G23L`>k;c+WCr=;POKO-< zCoggsx678ed=4!%=>PBJM2%1Lf|;|i7pjh@<2R;M0Yg{prdrxBQRi6x*hPf1mQ_QR z>72}R?WzLQk3t#-(6z+WY%&RwDxpYu?t~7`+ed1T;&C3i!uxj3fWTRNl zQNwEwScnP=Wvt+TD!;%W3SlOJpDNbe@U}L77&*YK#Q4m&`#(K=Byp>aLdB~o2_CcK zjwJFbCZ4U6wb%Vpfq-RKj$KKhuxG2YP&|(>q zM?WD^ghQF&#j&kz$85A4fvVpQ(?(-}=>{W76H@IGcfm+QxD=B2u}cN7F4Ohjud0yy z7Dx9WnmB0p;m+c$ikMQe~)NRk;Y;xo&Y@Dc-7K*2H>VxLX6i^LvsluZ@i0PU)ZX;ydU-8yo826g@T zP3{vAU|k5@YSjnL#7_3V+=GeYeLBiOtJ8B|w8uCB5j- zLj3g?$NkOlN@wIzbo8G4zY&)&Gnlqihk?+uf4lJ9K_IMDMDfzp9uS`hi!G=gkcxf(qB_Gnoxp2&rDP@T3O}D4HAOW2-H$Tdh{4;(Z`^h36q9 z7`P&al=CMNvz>J!%M$B^x>&7)5Nd)Pgh68_IaLK8i_DHctu6Zf0F@AN!XN^OLa;$k zHa{zQV58H=Qc^p%bs0kUQIZ~xiDzzzM%dbL36st_ZG0H-B06Z{=zle#XoLUu`C!H= zqE7(QFC$h#lx1c=3+)1xS`@3+2CmtA!+`o+LD$C_u*&F{0CPg`2!`h_bD(6)kv}C) z07|aYB7hLoUcm^tceZy3HnRo}5pItM!)sSxW;F?K0b*zZmJ}t@1<8HODqLh`aKEJ9 zPj>r8Ep{an=gu*j8poN@YQ89v`@HAcmoc4n4La>!mi5Rw){zPLav`inF4{83L+|+N z$hCfvJ8Ku_l9a|s(CH12zLMBo>VXrIslZDHHx?SsL)kl0_OWqbWxL>D!8z62v4O~f z<|%Y>%1c%;bP9hGGp$2T^dXbDQfUF0NqAvXG>!zMCe>-V8tnojPGe64v2{2AJiOJp zg|-yA_u#li?mkT7m?4IHYri0CO&k~Cx?txl<(r`}vsyHhG5Q|YHtK_7H|3FI|>F(DCf&Y{|v!$#5=OSegs z{@q6IQn4hOQtDbTzBkixOoa*gzgQhc|1ZUpQlin8S{_t%KY4X(1j_*fJ;T&Qmsktr zfDug`^yOI#J0Enx4~(6OM>(%-ynb+&AA8+$w7$w7@0?Ui4S!v3fQcFOVo2SC!)#UC zVi9(eHx~$a3Pb2RK)klLUbSB?Bv~7O?={=ItM6z~l6BLg(pI_z7riR5R^D{KA9*); z(?vD=kqZ05!q{9~T+lc(U=4`H7@gi*Eh@0Q$Jf4~OMx5A^Fo(3TFv zNO zIJoM>P*$1)Jym4l-6~9{`gs0El&PfHpzD6(6ad;@3)%D6FuZP=_bCZ1{%t>ZDb4T1 zUavoW*7~kn1nV^Uyw;;33#c38tWCLimyD>z1wiA>i>QVsDN{$;%92wx44y~c`~kaD zEF(_mJuz&&ii>5f(YfjgnYfRQdkDR`WAn-fnNHkH?aur;rq1*yFl=JL(n0tBoX1jHWsUr&Ps5e&VhNG&fU>E{3u z5I}1P)Z;hq39*7U7+f8YAmif(8Pvnf8gJ(I&HV$Sy&$?X#3olK{ng~Fz0^g%i%NY= z`t{4&DkG@m$sXCVT~32Pt9qBj-f;<9u7f6vXAHBS-vM7|J(mF97u%7!vyt0e6WBq^V^iQ8PUjVzh<~0q3j;nB>*}uA|tmG{$bC^}=6=Wbf^Q(>#|aEMbqk z-}d33N_yMEY<8o_3>tMORM1As_>jP*V|>Eu-I4+I?XAcD@X9|{R+)z6=+h^c;VQI3 zSXRJJ?ke&z^WJ-Fqj8A{w@c?hU!uL6_gEg@#a;8(f^v{OwpaFaSn%pmU!}BXBUvKYx#8$Nh~~UuB_!#ci_!F_lw-iS zXvs0+<$65~?B!1uvsUmFCAzqW2i)KP1T&n8+$zNS{^`V8Us;~+Z;L+uW&~wnUGh@{ zp!I|F+)*IXY!nHdG(2?=9==SD)!@lwP2Q|N&)}zoXC|3)kf2zVU1HB+2=~9u3UJQH zj3U+Xu`{@^yX1SM3j7YAo;aZX<=5!^6GUlo@IqMCWc4_h<|k)T$ELo-4p|vEZ?4e06jn{`m$h^v&2QwFT+sR`@5|&e zqm-uwgn_q$p76!p?#ta8fk>P>{IApI>N;`-6YS`7^9K-uEL!k7^)3Z;vK-$4sNPod z1Ku5@u|Cr0$`_|e0II-lg3M~Cq#g2oC5P2jAh!H#so%aU8iOvu-h~UigSadUrt0nP zG+y|rVYkjFc3Ea_mt9>JplC3>E&9P-H$a`866QYd?}lT}J~XKkEt3tV`Gw3{W(~+R z8+9CR50YHNF$s*rJhVGN?Q)PoS-tg=HGF>954D(_SF5Q(x1V%{irh%$i};4WDj+y) z{z`tDwxWG0l3ISa+5+dG;!KP0(>+XuPcCVZQ+p_2;i57nYgcGFnMxR(R?|V57uf$gOrLA`-1Q)^XXPZXT@N z#D=lilD76+YfZO4JG6_-Jw3xwa|DBWx#)QU^iM7-uIFva9q~jJJxCb7r=?9p!k>(df@+GY+sa`+3Rawi7#IfvgNFd+LNp2D?FR`o=e%VAKLOY@`x8FCdP$v4f3 zk6&`0^tb1Hw(0ZEDjN;{Z$#1?{;|}=AdmWjuM8I$f5R;Bi#k!z%Ss7r=On6#i&1~3 zkEV7Wz8h1GD`Y||oZii=o7V07?BBa>YJ1kToUfdK`@UMaR)-$CLO7|5?x22pGa)-q zY|Fd2=LEo%-b%|pAtBtJ6C6A21jpdv#5MxMZubTmvlITWxolgpoZV!&oD#kExE85q~(-y@%}zu0;0 zzAcg$aOQ>4Taasm?H1xHI7>Ly&TbVa6x~BVQPSXy1{(=NAG|<@3xt&C3(j`>mepFYi;iFOi(!P27JNvO!n#<5xaMtHLlZTnH4$L^JtG5IjRw6I}7a89gw(krl* zVJ9Blls&uGO*`YeT2`ur-NtceFI5^o{Pe@Ng$)_E9T;Lk4QO%wcy{mT(|I?lWBp}9 zk4%(#os&by(XXH=^UxA0zO8oGV>M4BOfR*T*?uQE3{;-I(G%!rh&n3+p}cmGgBkyM5Z%vn(3RHhIc#IF?J_F{8DriGikj_r5ZCBM1XAcs zAm}g)b2>a*#7MU}QqHBYT+G+lA@q-bC9Y{V+)MQr6Axh1!MI@?(kd6F6-2S84zhWI z9RcDww19cgDcWXb0bHTXm5HOF`-E9&fql^|(Zp0p2tt5OfB`l%6Q*QHjKXnJr{VOA zwPxgFfvG9seBP-zMz8D`1L*$)bz*-x3NFV-nlC2RG`Ozmc$qPt8Y5qMqZ^PyO`W7h zx+MbkEcB-48MqLj?rp-+ONWEJ9JHYb&+hDpf#S(uvY{n(l~Os#X+9s}gD^Ryo4Yop z!DXc*hmfdEr|(q9ZW!W0u#GYXwbY5b8~@&+^V!@}8OlAqoPH55qD=S~M7Ra4 zD5L&dqoXNo@%+7|bm4ndW`%zb;f`7F-FYUSH;85??-dqmv`-rn?J&p+gv8Qut`wIi zh~)zrZ8lg=~9E zn9%=2t#!|WEz06j#_$>8h}q*W;adLXX4?6`jDi@G?dqst2U)3jCov{Sb#zhCNfKR- zIc&I)^hl{HB4SFeQg&I}N+y9T+@k|n#r@3j>kDN`f~8yv2z=~OG*qdiw{IehGZ>l( zF$zuH=^DqpEd{=;pN&l$XWCWIS&fxMb&|y0K$QwakwzEvKKz!(B&KGG&}9`UVq>(D z-{gvi0r=DD0@+vjo>VyJ7I&^tRhJan`&5?-fC%2EzO{vg(Zz$YTz7{$&!UW=toyTX zzfR!6qMm~Q|Mf=wL*KZ@gZF=1V!kws9ZQdjP2>3va5t96Fvc{m`t^-o%5BxHjxFp` zi)x^ijoyO@bAj=f%@wjX85(4Gbz|l(W%X3{)_U*m>cx7CkJ4)Q^d7M~DdONP!h>LD z?lP^&+t`9ajSN2U+t^x`JQLuyC1=m()Tu`hocy_G;En9Y9;v)ACVShdtLq!wuD3?> za?=fGWs3A zqL%_9PRjXFUC;(n;qSxdGP{DVicU#6FP3smMbDv}wU%~m1sY{OP1mmSH7`o*_zqZd z9`TcvaG5%9xi*doi_D?wo4L`W6~U?{ABDB}-Hy(M$pW1YB}X^{W)W%fOCEKZ*(wMp zukJomC5|jgkm3W#icb^!gB5^p5nT%H^@-W>$IdGO{U>MD%1(OTlcOUqYx7S}+XMjE zIfNkmkbDtbBAbTTr3F3uO3f-(=VVxJQX>hK*Eb?w7x~T!ZR$;f!V)z1f0(Kqt;EWw zXk6Rd0?)QGd{+vUcX)s7Mn#7Mo2bhkt@j@pd)%{{?57-nl+Uyqk%mPYlz+mZc8>7E zpu4m`j?Mn-k#BIhBay7ITsHAp9o?n#I;WI139Yll@V-VT~>{?J@E`( z522y6DdZ?vvfNZ5F^?bL{pEYmS^OJ}a=G@!2CZc_pD5CvFIMxDftKU1slVrNT6r^A zi#V(8nX>m0K?KPnSU1Md=ag(>CUiUeARad93fhfL?w@}|H5GNb0Q%u}{iYNH|6XMj zsjSs9HmRls`%mgb@|2*`@_%||bNYQcEF`it!{^u()5r7)>@`=w;%5weiLn~k=b`~Q zy~62^F4>`@b7PX^xV!^1j36IpwZAPSZ#wdo8^+ah7c9AO60lr+n`E6zn^r}Iw^(~- zHkNgZP67W}o53sDp|&U8Wobn$arJf-V3XUi&ONY;HHSoDU+i7`-}&5vGalj} zCovN>{=+X!Ocy1_-!u_3IooqV$wC}2oerw%7-c6KTMuxpD*ncV85Y&Uu!SI$M-A*` z=z0gAZs>*a10?cgjURd0SS;;Vaf_PXu5t9ydXAv&Uv}Dt09Z;)ibA*fSJQr-g@7H} zEm?BUsoV{$iZ&@~27Ab1VOg)6yvn4V2?@8M|^6$2~TyHc9dPtFJ8^LrdYbz>J0O{7AOaMmqQ>b5*1brS)~b?hco8V=Rt#U zS~lR##KcEV9xM(xaz<`oNS02w&pg3bpY)g1L6e$vF43mxJu>qGSrboGghurkQaIRP z;9PSVYzXa=>LOIHiY31_ZZ*V||y~20~^7dvxLFW}rmJpU}CFb1-iPOz>l~ z6g;P%oxBFsv|+|HShq4P%=DtOnm5NzPU0&7PZsbFC%g(?ntDeFYV~KeN2^?APW`+` zJWW`_BOxI1B2}KBT@Iar%U^1Hs-(;$Vw} zJFneb=@-Aq2poX-fvD~~^5vVF3$4BYeP9A9q7RWPE5KP_K-!`D-O4jD{T}AD#^iZr zWD{av8>32$%bm`8^6=-1Rz!TeUuLY`Bs((BO@Omq(g}v*4Y!t`S?Xd?6EolCDwyKY zVG4Gb=(xuQWP0!kvV3aX7YDif~?)Q8K~G%;1Vn}XaDcTGpaN(|RvCgwk%&h%+U z7+T=ebE`}p{)`(q@ z$~<^QCatN=%kJ#ySlzg`tma3~+Vbz9d1@2^ zl5cIi|Ie{a5GxZFsRxD-4SW}+rYEb7Kz=}p2wxX2$-P>L_ij`&*nGMd_Q?tp)jm|Y zQl*wot;y$H zC3%VY=FM(P#AOS7b>Zv756XRS!MNjJlLwWX7xQ*Y;4?=84oeRQS_KO9Zl2R3Ld=)}RR5A;J^-BJQNo8@(|5~6&Yun{M2>=iOk#^O{Zf%Eu@#D= zio9Gc$c1{gymv>zkJ9=FiG-t})w zK9OXZ5=)^QUbs^um-h?>>ktqKaJwT3_0w9aNLefS!7b#$Vd70Vv9@SIGPg0E0rKvS z`4#n%f*Z}YSDh>ft4o<{NIBkN-JGH%BD!yC=oFk2AL&fNGLKualRp>w`qaK)hBDo{ zZ5Iyo$Pi5yv(!*XjjGd4b3qZ2qKyVdj!dPn{IfpgXBaVSK&i{aDG}Z zXsveovTQ+7`oPE>kQ3%fq%JO6)h)5l?etu>*F=MXfm18PlO8#F6qB!B7dT=7LqNR0 zQriz`tQCK2NN0m|25e+>i>4p{X(sjVeek`;AIXkb-sr&Ifkcy1Cvi`(&L3|9S)fC$G8SKe%oMh} zJEVhOt+s+`5BAi~3I?ufyK{j#6UwGatwdJ-rUWOmEPL*fOOSy4F}^%|=r5D0RiX}z&sqE% z#(aH7jcLZ}nkiss&<;Rf#aBhfd!W}axxU9j{$zSnGk{NB(e=na*<{lpG6k2C0#Bwo z>B2w@pSbur&aL%1&HJM!(r_jzDIW(xLdXeSU$H)5-vY zJ+t&&?7+U6zC7ul4b2?y8O)HzHgg2of1>vma6Ncz?1Os=h!lB@fTS~Pa7j%>OGYEH7C z5Vpg`YJ?rZt$hT`O%MCM6kNzNXf?rUO88z%*Q0!9CLE z0!2*C`Xjic@qsI-V|JB2ha)d_T*&UbaC<;VLRrd?IYsTCm@z~$l>kh*OImmp=1=(a z@42sXq?YQQLKUr1%2u_q_WUS zr=_%m)Ib!U+!{PNL3U+LWoZ|Vu|e{A(_{r7@YP&~fCdkUvzmbQVuANQQDXI#B(S|$ z4YIWa(VMZpr3zNxogW9Y^ExnO63+XiR+N*$mCC0Ww7=WqSiC=r61~8QUr6N*L5BE) z9imOAUctm!5D{|rT&a1jDqO(?OajpY!3fOG|mhKtvv3z zi*Up)FLFb5YV%{yk%QhkOhLpsy)GR{xmGN-+z5z+C~-OJTzk&E5vM(Z!xri`_jLa- zsGG32v%Hx%WKWN^15AWOt!T4$$iQSc$ne&RoXS48rJ2t?L3XgxF)4dD}gBB^Pv7 z=*jmncv(i7bzjec`Eh(U``b2|a*HE0t;VlD_x_#H+dCL ztEx^P!dK_sq`z-%QouNm(;ixYVi?|x_6?1&YYTBh{d!+y#ExJF1cBkO&Ct&Se6S-p zVHzIL9caU)_VQoP0xa!WcvvXCS6M5$F?s0yo^Ag%*IW5)oy$VJ;IOLdg%O!_;kc9m zLG-2@&>UrJaiH=RW2VtpA;G-(Z9U7q3gELBA~$o;)K4)ITKsCGRjs?eU>6&9ltmY@ z{q_Bq-A~g(H9*y=j2Hk>=sS70Th+->Do_k)d56Bt-c8r+p#~cgUnwFwlwv$Li9T_0 z438S%k#5<%z7a)k$sfJ@XSTquu)?#PiIjcD+=o`x+M9R zEr6x<7_`bB@$O^wQjFRARRmkHTNV0uJA339)w%{iNN0Z8;dd2kjJsFEk)~Jl2A`@z z#!XnWWLCx?UBX7l!6Kn!dO#Ils4-)#zQ~-CgBmLtr%eSQqZ?u-lL3Y7l7(^+MuQB& zHXA$5aKjl2(LBDLZX;NZFi8j3iUZbK_7 zR(wh`GEI9>!3F9lI-nTvK|%_g!pPMF1iRm6)P!AoHDYI&Rw1N6O=1#H>J1-I81aOp z_UBlz3b{ODl=07P201^PvU2=}@#<*A=9Nqr)2}+@TI@c1$)H5yD%uM;)Ngqqs_ZsQnZ1e~%F%#5s%I}Ar^lEWmbO@vhy!;I+z7cv(5KeFP2dtC z4*-hzkP@jbH7_cdgdx9emrES`LSI}a;-|jeCoSK_T`Do8SqdTSN>YZ8JLGwGPl4bg z-N*SzM?wxCMNP(N)Vq@Ev2q#9TrktUrnK$1=HT}qpSGL@s5AdW{&*E6!pbee*XPnj zp8=z21pRSf2J5-qzy=j9{N$&7)#Rx6AR3C?93*net*u#rDoOyQ=FjUW-9Mb8-JM`pP`r zyQIycAq4f~%WitHl}Fy?t1p1}D|5lKlWz?2odlT9A(X$pbRCw5ZfM-z`^aH(?sS`nNW4+GDarmQNc(OjY zl=@|Ld5z9f4QrQK-(y}u`7Sqen5Xu1y7fY@s6f|NfY7zCg51e{6UtiFYj<%Ou+*=^f@KOyGH6 zs*Oy??XM;nm_SCQRL~nzG%5nWwl6XQ#g&@P4f9)ptU)35^RX*}(-%{)Tnju@s6$;} z!1RP%%S1da2a_7F0HC;qe1r9=UWj#F;R!8p0T_4Pc}K&t>*`!NxiTj7iZpIgg;M|5 z!uN)eK#O}8^5kQ%wo|3hxAJn^bgw0NMwq^6DAK-m3Q~X9bDfJw3n-AJF5(s6kS9(> zT2DNT!C<8ThM15xaK!v^fVQ?FsJ}v#lQk*`#ubJHTP*ndiK}&yBK^YGqm>DJD3yaD zv7Zj8m`3wNUP=99CezBmb!3x2LekU1>)_yykc%ef06gqzx*T8M$kEvN!L$On;Ne2f z;?5UmJZ|a1FCV1A>hCU9ueGdSzkQoG-6O92Lb98hdGy}%fwk`;{8oyl>M0(NE2NoifX0uy3yuGgdJ^#X; zEEJ!)bc)K9fhp>uSr^AJxA3wz2{@NbeZIOH478qBxNFpRN~Mt_hm`<}bY$hHCEGYjp}+@E<*UMDRT$P`0(6ndW=9z? z!q-W5#}A(NsyK&m27F(Cw4lB2Og%nsJyr3kcyl@CTjM=>|K`^uOJ;Tkz-G@#8Z*2mKH@(q<5%bHU`mN_6aa zQZ^G#F>iu}oieWigj;c=7KTr6fQ+^EiKG%{KwwR=mTKD(td}xn0$}V35&Q~1vOh+* z&f6o2vhC8K*Kn_l7IM`VR`1IcIhieq;Br`Kce1^;IZ|GUDffvmf)wUABsA5RnQ0!W zVpBT5Ys^lEmB?D7Kn!j%rtCy5AS6);BFe`9e;e0?R4qb(Ix){?;UDfmmPopG(|nx=L(&+|fAiA}9N3+ZIB|GmIQ6OUXKFYbL53$1mA1l4o$uO!dY4Fp8X(=2m~A%M z%%%(xage1pc7A{+CRO~`k$iX{B;ad^kuF9CBrSsvoQX=Bwm?;Qj$v_jYp|6`#{m?F z+gS#Hn44(Z70nJ*vSmpTj7vaMiVHF7cbnXnVObmFnP4(CM* zbpbct2pZAs8)SeXBK<9tva+v7Z3|2Q{pi|JeFS4oxbY+!mxawnT<=5 z4n#*L#gK`4JrOBuQ3bk)ptO4uHoy_aJ z?BycE!n1#dOMlV*jIa;K5q-dWdHD0W8RB1h8}f(l;)w4EA`|YkcTn=AD2i<@8J7uo zFm{0v*pZi(|L)DI{dH(9sLmm z&rg+Br62B=;BrNvG~-`ZPVpF-IHv9>5;#Q>&GFM1spgB(3M~-v> z>3?dP9Ey}^m&R*b5CQG*MXepR_J5IO8`5vpi*alxAXDSuHSq`oMh5?`jZ2kKvW>8tP5HlXiey_ zUlM7k$qCRhR_X>A zg3@W>kMzg#b5~&Xs=Y5A;u<0o8C{72OO#6l<={RtnN|dINrpIwy%u0(*JCh931MWz z-eSEhYXNV1vAw+i>u&lpHGmLNCt{Ws^rz!$eEL?#tc%trhrB4(Ne_ zkWd{A7b$wwTeJy~Mh+07gbl2HVifJOm<1NW^Hj`!(E{o6kos93>X&rwi{`O(#gx*r zNFSQFwI!>F)23+vV#;LDxP+;be~OarEUG?S6i?`6$ia?;Q3=hj>n$$BJy~o8-~X+b z+t`}Wp!LS;QSzT^!b>a@k_nDp!%#{}UDb;?nkg*y(H^evPmS*VlShJDt)LaD@)OR4 z+}s}GY|XAp0!iJMTfGnCKXON?PWNiJ(M8HuD|c{u3uJ1o=2#3z@fX+4E3Ue zQu;k1ivu>TM?g1Bsoe6$aCr5Zh_b#KPPnuY#iVF;Ykh*ew!KY!XIpi_L4|Uo*A=Iy zA0wi>)v59)_L|0W^xym&0!b>XM4ri|qD91&V{R=K@>J({WNf3YDgZhdqYabz^h9pb zqeQfxCAY!@`p|PvH7=u2=zwKPnYAM*WPYPedV7|j5(ixPr)v_U2}fk~vt;`ZB-Ab$ zl~#~^E5KUjBYb2cpN2nYGkN#R%+QL)JFJuQJq#xu;mUdbs{Rt8aP2p%NBzR(uzXEx zE9W*J>=HjXe0(1MME>MQ6)i_;)qi)zB=z>Z;QS&no^rhn&YLfXhZYXvT8i>gY^%E~ zOZgXi%RK*_Kq(}s-Pf6tEgSYWM4Cy3ZovcyhUhb4Lg-|Yn_@`TQFS#%>sgALDkSg6 zhrKOF$mrdjHO+zr7fBnE%;)qri3}b;c-_IK>Wrp!;Q2;yC3R(BGq)3Hsoh3J=I(R= zKFD#f@A(EKyZe1RK0_g9HAD)EefW*`2@HSo0n2+lItB$b1WKsxJrxG@&2+=tb-(x* zu^^NXY^XZQ@Z>^2SdUQWpH4=oobTrJ*oP;a6oyO!HAU?L+uAr($AUj6Djwc zMiC-8qzQVK3~+T2-#Iky$B8;j(E3EVCT{j#MO!Gmx^qystF;tUJEWMss(jK@r+a_w zS=x8s^~>M@`9FKPo?oY;W!7W?R_KB~TguAIuUXSr3hZm8z)}~^JosWQ-a9PMVLUte zX1i!?F{ZwJL1OcSGmLCts`sg<+9PfTS`!`IJG6pUS-wrvvzf~C9OuB;E3$jqUxnQEV0btJTz6Uhz}iYZw;Iefum`E_G=<{VJIL z1)s#MSNAw^r|aij3z^zoxLHk7XvfU)Up+VKy=(3KiG?XzPXhnYaz}~P;KI~5;<*mW z*6X6shN#E!*h%|kH5gynGVZkC!-E~8y`eNoo2wtki9s^Ri@YV3CX>-KO5lT|rp!LF zQ9o@Z>R2CGB;T5W&L7jO7G+@YY&0CzHaK$Qad7T5T+5kJrg?z;?e!kpol)m|){=px zjQWL*Gh!Gzex`Th>=Mn|A2xeP-;!{t_$MB1L#rE(NLqq8cEYTVoTvOcXc?5~Q8d!j zNGIR{hD8KFYDX8-Xi8!D@O4QkO3JNc54r$;n=SIjrrUq)kg!=HEJ6snt@~3bRQ-(P z8fW|>**N&QFEi1Fs}J;d)Y&!TXr&*PMG|RGtMnR^m5x*dT{?*w#%cwj@=PNA?88cNSji|XxWqPx z-WjpN2}K+K;pFpU#B4Hp6n8F*bL*Q5XOCiIvR+ew(elPpKmb!Wk%RZ@?0&bNN0SWls|HkkLb&6_rv+IzUCqOG_QI z`#5az4mZ>JOB|jJiw!;CF}4wTo5UvY+}YD|@zqY2$gg6fU{>$9H<9TNPR!C>=Zv9y z`yArwCpzdfLbW{IxEk!C?`43_K}_yP>sV-)ygxrG?2cV&s2tefm!1su-hh3O+Fik+ zTX2tn{Y(G_5;ZzBTaac&AROC`6$j-{NItBbS_*ypwrcuBLl`R+rjJG{gvM1B(jma& zhmRI6Q?ma6QZB=(Rl7GPerWVWz_%D|IJAf)x~u7sQP$+eMMQGAnzGIm&%l@QaK!qn zpUTon89)?uO62Q_M43Wk1}&fdo@krOF&!w{Ds&3Psf8xJDEl1LJ^?=dRbwGeiT)7) z0v1PrNu%W%#SefSVbGsfl5_)4PP`_k{jH&k-45^+v&m16k>L%x7`PuE_MZ~U4|CN0 zMfKoD{_2UHIqCDv^oel`E7uf-ZST}-hG90&cECXy@2TVU&8Q_>P6n@rD=RpSZ@0a_HXfi~+ntBpkwq{n(9hO|{bp`#T~RIH3RqJdycEPV2WStnw$X=co%A zyufj*S-rP%%6<2HDU9}72TgfohEs%aH`G@OY(v{xgr68#p(3AyYvLWCv3(}pZ+pxE ztm5x2$E7STt?u4W8U~Od)#&Mtpgp2G0vKV`ZKMtgwO|q&HRZwpur?D(HU66TJ#sOD z5(4>+CTWAwuLGlMbPUD01)hH;CPBkSja?ni<( zS-E=?2&oYwF4d3Td^0~r^mXo8y>uqDdHsp0C_B#f&#;SS?Gn&Co2)Vmfa2?i5ZI%M z!tDigld@Fer}%=+qQyGKDHcJ9;sxQ4w$=(Mi=k15jBU5)nye$Q0~-z3-wCs6t1`Y5OoGziuRIU^HTsH585>_uU zmmeWy8Km_ux{}7B7MQ564JPSs9IDx<$t*LJwaiB^(1B!!T*j1AaT5@5;rP4i(!&rt zX+fGqp>JPfhcMfs)VeR&H?smqv$F|$nDljMF{bT+q%UzK`jf%q5ch*ceR6N?=U}`Q zjmd>7+HeP=1%)QZi}?%s>M*t&|5mTsx@i}e#VEW-4PU&2HXSZ~dTtUeBMB|F?kkB4s*LjY z-%U1FejfeZnL?GmL>Z{~j>#`A(Dn4{fm5N+S^`-Au)4H6M?0TW?fDTu8Un6>z3lQp zRpcRbEFzYFMY+n&FHR=Czr=d+#wrPNid9_iB8geP3_of+8KMjZXBW+h(W{RHc>MDw zj(Ph4Qn2LqerdSx!yHwMU7rBI?@T}t%=Q%)hpGc&{@|G{H}rN$A}OgVLO}FtJ%2DN zk)m#Q^bmY@M6`BLX#F*dxm@Q85XK(V-jR~?5OE=)HSi=Ea9LB3J zUA0>LX8?EUPNdSWoKGAz2WP53Iyy5x9i&UKfaWi+(O(rqD6cXMbobj*nafW^QUTW3 zrH~u&!Y8pOB%kNS?`IGIl;bCUvJ!_3%0fH4&Xrd`LXE#Pvs|qzZ=hUe-m6p?>oLZI z_F@rvW{|WU#}qchbsl;}&~N?^MIbuWNR3wHq z?SUo7esj`>SEXEOv;O#WaQ((ecvA&6>EM%{TQhxEJm{dgHc`m$mDgnVFlF(r{X`Oc zfcj1Ymm<(Svx7%p8IP(E#*Z~wZmSMiFm_%1>!(1`E?C= z%<(CMP~30T-?ix!?9biEPmtE#9>sm9P^hymv<|Y7KL^3kj4SM-G~|hjbhrJlyXPbK z{7JP$cQvnYFtI0+K-Bft2QX`&Il+99ic6gSUm1wOb_{ zEToQZO^_ypAn+8leQjNal!YgDIM=lcN_RRv`uLrwxRWV73GSp)Fujg?;sud?wm%r6 zHnN4wa|_^#ptIHBNgr~sFUoM~GN@0*KLQl0=^{CK-ZyM$@0%`l8iSDM4WxdwYM<3? z2CGTdCyJ#nw-#M%&me!HCB^fxtZ3VXcjzuI-*@qWTOr>+q^30N zHAnJ!GzlLC_2i8odK3|H*o7Xk0-1EL9)0J<-6CGr=z77#EU#~4tc3wO2za5?Z`o5g z+?IX~^~BaVG+)E>*wn?m-JT~JCq1&rtdCRiV7N5}{o$!^y{n*C0$Oy~nTA-n`Zr?^ z5zcHOE7yDN59<*cd_GxV*b72AvDMSB1A>H%x~-}+jcZmFr>s}Kk=+2{^H)bb?b?#y zB<9!>VYbb@uHTo&u?)H)H2DRm94ZQrKO9M3Rbj>;u5s{!zW)w{iQw=60QipRC)T%a zXaqtO)*`H`TsF-yc;nr(cESmgNL&=(M-I=Fa0|1cy4V=W%)tslB04>&wS2FT7-{m) zUOPmfghUES&9LM4Zc+cInjYr(lJarvTO9_>BRcthhD73e$r)0zxbV!@lg}dXwIP)) z2hF1*K^o?7bAQgz_fIAqs{}sT^t8>W5FSuHl3yihGP*7SscE_cA`QbuBdPH4JxM{R z!}YM(mB2)9Evj7Xf|`#gG2Exz`)57zer{lEJ_PSd7Ufo)A3&#C6upsPf@HOP?M<*= z7AS~O#gs3So1)S2+0zwKnToZ#mTcc|SWLc2B8DZE1JcE0;VioHosWs@5U}tgN(w8u zAI>|$R$6gTf%(-1mwtc7hn;fWI;h=Mw1Ntz9#Bq+C;rjTbA|&rcq17DIWmJOG($v+ znk5&Q=IS!9lW6$QI|~BMQ^bMv2(xN`+NR@5YaRc$4YDS)@J%+`qjy*L6KV-Q36iz$ zpxghcZoxqwOw~!uH2kxzLJs`mwS!naf-LL~a4YK@ooS&Y`JES^MPeNT8j{sB^({vb z4W~CFeaQ`z2GnbABEaL6lNUS!zX-Qd_N`lHH^L{w>JiOz5#CU+Y!ToI2}&CRAnw-< zbdMJV-(4uTa<-&a7pXTxpOfjt*-&~4c+qBcU#u8C7;3?D@KLQ)9sHzSOgE`GsVd7o zOsDPtl{#UOSYDYG6*=1xVq$y}KOTn!j~_+hM5t~5-$9qmXTE?64$!2`quaJsxTVt6 z>POV_W~sEpoH|yEHWWvCdRFUFRXCZ+C_XDs6PKWWQ|H|?jOdFhQH2u`79{gNbuGSa zZ8IHk_lC--Di7Ko>4(?y^cbyqpk+}&KwB>`H;7(k#XU4yFI`zPQ)xN{XGAZ_^;c6N z>cck9^TtgBtUf$WNAuIAkVyN3<1H?07551ec%?X-YMp5L3*LL$2fV-JfV=HFVIDL5 zNd@Hu0qiZL^f6?v&I(i?B_!SpnD72KyqPSiT_q~3!*E$tY6k;0YdzyQqeG(MpYKE{ zWnxk^gd+2pKu|*`^g%l?R!Q^{!L^-DKus{(W78!5C9M}ap0NUVOULsDm!TBPX#-C& z18(0tb`(;uoAZ^*Nw2K!2P1TVI5LUv`~EaH00s4IHH5zlzSjla)tOj1cj>8;oMK&!^kiA-VP@yuT8U-6O{h#WM zwHn41z$!3dQL}n;i%i01MQ;+`;1hd>#9l!m7z}0zi%On9Z_uWF7)nG77)>Nm9zg3) zYHSeD>M?+RY^d+R3#e?)3-DqKSSL4AJv={V)wyh1{?TnlhYKYP1q?tK&(){GN8p7I zOh|RWhLG*euqyv<0y_sJ)JLz=Q_FD?Kx?&n|5Z(55Xh9V)Ay_Cb>G&Ead;5*bbG_SU#rbJ`rFfz{)60hKxh35@2uqkjf#;;+3D`%Gvbc}IX_W26}N6&(XKUPtSdBfQv4pd=}raUD(cIkYQD3D zc5O6#!AbIgBBh3+0WG$d%Iv+`-vAWqCRa18B8D5a*yiPtaF9@7h8ZRZZWvC4dO-pS ze-*V3;Wz0|b&|24Je#IiNboR=Tiqj+JUO}dEiB8$e8qE{j`PE50#~xuwJBRr$v?G6 zq|D`BPRXqEqGrdA92#oYJ@>f7nQ$(TCtiwXJ6BQRm|pRcSz^DHz4!P1$BUZCRR6Bb zqipVP08vdlA=xp8f149MVh#oKwe}E8_uu6Saq~rSk>YtWj{U!Px*65-hjsTiY#O6+ zP-7ncDE`og?n@(@xPk$|=#3tdRpcz(;D_Z4Z2Q%h@xA$>MJ+WaF~KOKD47c|!L!Y+ zh5DEVXxp?7jIzKR`Fz}O6u3{;gL#f|3wJtiBbM528i63+Y1VCgH!a8Y7FOB2*TN4h zdFr^)#y7tPa(SS#sBmT))D!6yZ{o8S&VLqM59ll?U7jYCmwU(}2X{+?2)+Z4iW9=t z`w7gM;1!&4d&onzu)T@Cn6JSJ2}X(8jb|cXaYNR2SpTJ5YK&js02QN-_ujle&V@L9 z>sFQx6D2G?%b251VK z^G2m*r^lilTqCy*n603Y@9$n5_m^ zQD+*eIkfL-4`||Fmj`%&@d78H>)2MKs~FNXrO(cbG6#FtZtr^qmvy`1&WapX>H=u& z30>uHCr-io7i9?{-CKlelQ=s3YuI~%fP^OIAZsN)WfjA^Q15JyeTaI$ZnTF`u9N9r zoclWWk!@qH6q>FR@>(*abW*7s=y)n-ze5u!#YKghT*IxT&hVPDPjDe|C0aGlm?~w| zMdEI~TYkN~uXL-J29sA4Ua~PSE@=PUn5qba+$-B6k%1`j!9@G0zo!&8RhMX`hZH}o zR;hzDN@mnwqNP||y8q4Ch(?`}+t)696gU4|5{;kZt8rI>V%BUvx{D_x)Nar?JUb~ldW&0vueW6STu1a_Tf=BeV~wH|gSpGCQ%RobQbT z-9zm~cE!}DPXg=e5qRzPA5NkrfrJi9)|KyATu5dT=VittA^WK&w~45kH)OcIdU^!7 ze>|Xcx?wwE;vRtrHbLgZ`F^KQ@Bd__9z|2lMV$aHWJ~Stx_l}6>W`0_&vZy>saPvE zE{)NpKwcU<6uJ-UxXO;tjuMApoN!8fdAKSJ)y`9*{nI%T6qD)Dp42$P0C@MW)W9!# zwQCn#RP+*zlg$~Zu+U9fOj97f`QfB+qL!&5PB2${mbJPy+FJr%6~2Q~2{dIp5U z$HE89!kssIVKeUlPhA)wNVVdNdYLS(%9@x%P8nRV_3<<~oF8ZCr_j*?C}Eazi!Zxu+` z0cZ|vWtoz_pTc2iU5_!98SGPJO!{qjFV#B6|BL_C?9~yB3&7B3qpb5wB7lrj(h-rI zqc%mUs!%i^VPEjibMb92zFfkEhR&=?xQY(Yl=pPfUYS;GemAnnzwpb}jtJVVj-T{d z^0VxoP)iOTkL*H*5&SysdCL&hgnTf%G&UxBNAVw_&hVp%rjTYvx%4f2UBpf=_N)mv zAdj3xHbg>MZ!N+?WhMO+TRZ4AC%gjL2T32#eI8>SW88v)i0=Y5v~T7>?h|!K_0I?? z)|#0|`PbE$@>B7cMD0!_EIpZ`N+oHe&M4O*@vJ|p0BMCqj+evy_6A00P9J-aZf;Xp z7y-LSNpdQnX|Mo}BSc01W+n*vbzO<3AYs|NDa9WHu`507k?x7B>Pji=IecJ#7~?Iv zy+!x}0ft}l6RID71v+reb=uBpJLQp3EXP!hEnF>_>`Sf01N}j7N+-Ux8L>l3HfWg1 zv?+C-&BivBwS;HYnf_t7AMD=Cl`Y5QH@05mz(n>F<13ss=oF7uKI9H9I2cuFc43gv z^xy~TQOojIN1cH8d7|j@Gfcen;&h;ksIwteQUo?YC)sxty784jkyry!2_PNLyxuIq zZKn9~vZOaTlY|ICbrv;`susOE8{R_VXC=T+yi$Wxxj z$tfREFxOI$AKiL#4pCayIJ6#mf;v+-_Ll0FsQz5i_GmQ6_Syxb(a*5$0NX?Q^9`c_ z5gmY1wdDHTJWN41qjuY6^;lTuX&4coKM_BW4HpFke>jO;h>#UIay9j(GM155y>(9m z11u%@WgLBxD5wtQn2B#fKJECY+i;_f82s6{&Qypyf5~;bP|Y?Z=FGXind=*bT|ZI< zaH>xV!<|Z=di(N$1>Fp4M^9wnhhQ}=c>8eE`wn+d7m_S-iCpyK zYt)%*=H$0rCtTAov~x|RpX5u;(&+%b5Q2Lsj3 zUrNyA&|r0&27%G-;#EKg>h%^ly$e<0)9C=vhoEG=Wr2}kP%p=avu5#VY)}6p_bL1u zYLp_<<1A#CW7UQ3AAywn56ChBZrzM)q+1c(u_dTh~b* z0_w)pCt8mb$*=WG?Br?2KtF>+$}gNDo^18+G+Z@eFxE@Xsv0uo?DR|wEkgzAVViED zPDtTRPe=DQS*q8vN%nT$$Y_-Y)wZ<*#4A5_#UerT@M={0z1aJ$0P|bCGxXUdH$2;> z2$L$jh*yX9U7kiX@wjs%QqgfKEWA|xgKu~sy95_dulx}FwSjR|) zSQ=oR50~3?s|-CRn1#Er^#j03azL!3Qz%#Z?ME_IgCB1BTy<P>P&}lDNI_jc z&}g*YfG0xG;pGcYQ?XRCY$dpp0z&LAtfa$2wJh1+*NDaiO2gH>UNO}d$@K|jbr^qb zIET%Zw8vOX;PYHs%k6857YK}0pS#r8y{hnQOshU&6i|Jj?~B3*yX1zQh!(^VbGt4m zg)t`sf{M+8cghsv7>Cs1$B9vpZoz#U(4CR8%3Gx@lt4)&cviZPE`Qs1ie#8(5)QPO(kCY5la)?;F3X{ZiK1%&#l)cMErDW#uRj zV~Ps>*g_YeC6YU4rsQiX%qgDez2W1_v`pm5G9!?;X>l3J7CnNUt)y!hR$|XSru4JK zgMR~{sGq`6RIRn4$6wf%TBnA_X^m~U3`_yvSafW)TQUWDy#6_iT)N9q8xCVe-W9u2 zzWWB{R!?Wzo+)=d!&@ZbG_7gX8iFQG8{)38ZA^wMFD`Ls!k0U<>7*Rgk!|c3`w?mY zp8t8rwVr5k)Kak7_S2SMA*whd=tYbc&&KMUFO$8~*~ zdb)Iuv#F2ggASFCR`C+b;3tAB!-ZgL54sE;1ThG{a6-?xeW7R0KT%`Hn){yc<~Y(h zT%oA5OWaePT9c*z#*Wa=Y{dGK&}^7>r|-TFmuW5(G8z7; zYW>WX+}H%x(*RV*&cJr`Cw1gf13%#YfeW0OG|fYrlJJ2 z_r@(20;ayN&{2pcBUE)n0G7QsnfW9U0kK=94v{W&&>$x8Nakr3EEPUToDwm)mXh@WbYxvra?Q*vd7eer&$y zI-YC!H5VuezK?0!B`8?&1E{ED+u!fzTpc^_+cnHO2NjxKLC6o%1DK*;chMh$KS$odw(!yc8qvtN&>+`vd5s6; zFEw})zT=~f{~?~MZCC6nSUx)|*z9VNP95AJvQxcUX*U)g?Vw+B+q!TOL~II^ak0BS zFw@+tTg(mjjto5*{cI)t9klF#f)N}=(zz*U|K=Sf6DpRCNP z;ISd2;uco#6~33+0%{b`gAnI>@TU4tq4>bOTt~Gmpaps@tt^p@E{i@V8z1WLn_*3Z zh`Czz(zcz=y!12DBStJ(yl+0`n5W)H!G7{+w;fEJjQOPPoR&R8rx=T1x^wcIu)+YG zII7H1dDfG3bqoNukG6Um%ghOZ8!2l#8IVh~$e}Gxr$R%Z$unG1TSd73EEL)qei?uZ z@t}h830D~$o-@bnB*16lvM!6(q>j%~;nt%^K>P#A=Av`mls6w)4BS>+@H(B7)&V%m z(pH9KV6yGLiXmPFmAGlW{Ct^pbqXMxs+l$BeMTZbjTiZJ-E%*28;a9kXAkn+t311I zZ`)b;_kwhSyo1-(U@cXW^1+x|c#8l8&)SE~bfNu^Fu~CkYVd=IenG`;HS^ygH&M>B zoYrUwyRsz%u{xdQli2LNznQ#UOL!?+ExZu{u|&xwxr$*pWOCvY)Bcxew_0B}tIYSj zH$beGBLj{JTWZ5)HR`fS(!bDd+qqIDbDX!H7mhEKS=|r8JL*C;wZCqhG!r8~vyqoZ zPHU0nQ{hjsr|I&Em$zvR5)oxTWyJQLOh@R7#!K{)4|5pofOM9d=}e^OhO z+!D+9J23|J4Q*gOjf3YP6)IA%8_tzqXlBf7>L@3&NBlkKn`qH?@ zpiSq4e`6!LcmzK`#h4+gPV zZhhs^S#o+TtxCT|d#m~R*csNi0M$d|QbH%~VT*<8aP-lEacW72$gkTB&@G#1n8CtC zR~6I4FE@DevZx?)u^^w-KC~Yp)taJoe$Fv8pJpP3ryVO;VjeLrPx&kwynM-)Q^BtM%o+AZ%Rw){ zyzuJQ+ln7te_EyX)vBFsm-;7{fYnK}MP4hWS8jQwtJVc&CKT3j(tKqRyHFTF?d7b{ zft~c2x~61{n`HyT^g=c&4aGt3Sh^qa!Ve!~;I}j+rlb-~d3Z>vDera?V^6W7CgtLB zQs7m;eHn#`%4KZ=I>C`L$+^-OU+5d=Aavx!%i@NA!|df&)CX>3-dzXL)Xn=6A}?3L zvgPUVb*i%Kdjrn^UZxhYQ9*I`q&g}rnKjO3l_!9C+AVRMht!!!|=e-K&c`N;>`A562dT==5>m+($o1 zbHq<4PS8F_Qz3+7NIZ}gX`iTL5xeD(ufJ|aZ>$*_?M>1lhw}Y4K7~wVhLLd?x(Z`A z#o)oC@A1?TYVU5nj-P2_5{Sp_NtO_@Y&vQ!07Bhayv)tY$+KNh5j8(+bu=5RTcy!> zbSi*65jZ*Wv=tHXxjmA-De`jD6}9JXDh3!OkDh>;J>MwN%&f8&>H*SLY|xKP-0~tV z1S$AYGfC0BCPNw}}RdWKv=sb)m)q|48 zRPlA^Xhd;yjzvOAy<4r;xZBeM{L;>vffx9G^8jM1G1G?=x9P3|?OOJFpmbC{0Izk2 zZjG=`0=|-@C19bf5TGtt)AIF+tWOpR;9)&_tgX!+Htkm^jjiY<(DtOCf9IQ7&^hJY z5ce9k&JliX=4S=OyHE!KM2`KQI&Rd<9Y{lz#;*8>9_}FdF8=U3K|mH_prH>(@Z)B1 z7aM76$$1YAPq;GtGV&Gzst}8UrTziH z;xOGuZ7@2z9q=22G7Al?XuJ6Jiq6-D>)uxm7FuU#9)`WWQ{Oi+LAl9J#=XAd@Y{w` z-qTX^l{h^__>bJ_vb8Ob%(nDhbpB5JP}7Z76XapnCIj|R#@MhZMmGRA5w=$vGLxIb z_)_b3<{6LAnVY+pWfjN!yc+!eQ3~AGwpA9EaX~W_5;Fg!pm$lbV}hG(T?QGBe0`3V zUf3adBEtVmq@<_Y0A7ii)NpH=WH^^XcjN%O? zW^n#&tj6hd1+Il5eG7xNV?9`a5G;>D9O`zs$huMj#IgxAa{*tZEAR_^nIS3lalQCV zY^Y#nekKlE#VgyBU_!Dt8{ZJFCucCGbg5AK_%>fun;f~yIKtsSS4Wzx0Vr6Qea}mS z?OI=;1K}$8tQ0Wrp&^TQ!pXE3$$sr>u0{HKam1<8TMwG4Eu>VyYo)y}m!+uKvLS%{ zINoMI=GRYcuRRr<2e_-*I-E-W1Y0`o=nb@-EO%;yoRmBZ@6HZ+6jFBl(FyWg2~a6;4NU6JMf0hX{{gw+CQTli9NdwN zn*XUHws+Kzd+y&M^TX$up)zvB4g&8hQ0Is3zmp$W@;%@sI1jc`3aV!lyJ#@V@XeM7 z{Q15LvsAa7)QbMT^KXaLE6s13O@cdWL4nYRaI#>^jo?N{#=)-SUJ>2TE$_UIDUbvM zfzVE8dtHFl6_x&UfS&)l(!O+|nYkz6uu_DK)&Bhp|I|ZoyTcRQ`lG={5#^Zkm-k~U zVTYbZtJIXW?1nNea>U+1EIqv}EQP^i(HJMd^W6kWt>ZBh8NCR;B$&5{#?D6vQF}6t z3_i4#*r}eLDy=q?UXpo0LaUVe=K@733``gRcPy8&jKKhLpj{=dtyg+XfrlVgaB{y* zAE1-nIsR$XO>m6G#sghEuF!3`LE1l5Bvd=Dq)um`K?{D&SLU2KQ>;ot5hZ&QCmSc9 zk>Eu<9kTs`Y~Y!YyJ5z9=mE|oZlNNWNaFHP22aVrUzNXTNYDpDXAV$)G83H)H$Ra+ z$ektHN9F9!yB9dXV5KkF?svZxQr?pX?Q~hQQzXnw1ow<}%D{S~!=+brh@LCGy*4Ec zzmG~!RXfL^_QIUZ$ISdpU;_`oF&v0{(O`?shZ>Q|j{Pc1mOvOPB`BB{0FJNtN#aH$ce0qoY)=!wSI_`uN_hnrB>5qn=uEQ|y< z?S^{Z;fp6UG6(~0DK2JpIKQ}-VK^xW8>MR5AGyw^%Uc5e_ ziF*&)|MfX2IDgxq#Ghvl7B8Kv^soGHLg|&*IqGo@rgeWWyto&cnp%xVaWS}6yK;PJ z4NO1WS53-IW=t_-%M`4NT!_{>e;BedSLFcsphHmhbqGRa7XVGV9nH%NPlj+9s`b4I zAVAuVFcmUQtS#rj$>^Hj4(-g&?c!{2BXVXC^WVguw77(RzzxMLF>`wvhi z=2xZFuYbfK<_+$bd4mzupvawF1vzR`7|JGa=5QgG;M_m)#`Rw%02=1SXixP5Hy5iF zc0cMiI29$z0%@P_q0vHj@~<7jNk1l^q{9dt zuP4TdGME{%pe14*{#WGGbrLrM8ysFJcp()_+Vd8vF~#f8u>#~?W*fJf(_?*!zfLGvRw=_i8A^K6^3 zZ-dLK>roy2#p=S9#?E(l{0`f=a-{WGO5V@i{8Sp?qxi+}GyEv#HofbkOZ43!dUz~^ zunGHKz4AkHg}`KVRaFnq&vOA)fnmV_e&3YY%HFUuE&Gh_t=S6RmY}NSCgh;3m~PD2 zATcy_2&s50E5nahRDi?Z@lVUIUXhGp{J-w__kKV4=$}Cw4)_BtbgP zyA4cH88Q}+?g^Tl?QYa|k{y0H_1Y_Ggr=v|n-FTv1Y$#quWQkdnMYmW!gv+L=z6^V z;SD-Dm)667zqkLcQ>;QG;cJ!iXe*02gwl98r5_>|_cRG5X-zH!LngBz*OI^d2~@I=Xb2m)P)fbBx@ z;>w3(|15<%q@sZI+8t$AblTV{2Z7HYdox`ftw^O^-4v<(AX9FE>Aniq4=Z-hSBDWL zXWk8zmf1hBCR4rIJ~yFTV$9P75YPN;^gqJa0nzuaz)*73!WkL&MluDsTr;FT(w$f{ zQg&+FQ8C287qrCT{%(e1#+P|aJ6}z&jf-*!4eL#Sdnf?3usZNb*H zR$l#3F-|8ZjIjKoN9;tEJf^F+Y~JEZc!j7Rr_218@X}3&g*U1)_8-$Ik6XShW;Hc^ zmU3w2=B7BO)-@^C6~o?Mwh^yJ9&xTcle)@F+IBe&9cHh{n2cm^g_wR!Mj$p%&$gtG zzk#}_49wgmzUk3GHu zv0EpC0D0c6b~iq&?JrH%+0?wfMDG@gvb*0KSSmE+^A>?0Kzhi(L{VgdQnwUA&F`ww zZePJiZ{i+!0{e>RbH{PM#wB3-AEV_=1UW-)3OmqdicJMkgJDL1jq^{Xy4`C^vhF}%)>1iw~-CaXuu0O|IQJU%}s5Mk)RrE5M9HE4Srf&#;2+E|S@PN`5_EjH&ze``23xOK95W24#mcoCqQ5F@5LSD+DlBjpt38QQx-`C``Ebt=O z8_S!>s$P8+gK+$NOXs+KEX-k)ir^7PznBgXbMkA3>W*SJ7gKO|EO0eknRM~jR()%|mMWee2sPK`?qexOIF??uY2Io5lALS7rRwbDIwvscZriD3q5 zn*M()v0^MzX!``E8jExz%Q)aAxcjHCza4Qu)xe^}wFPHf!)hy5j*MK2=ypxou3E89 zg_h_l5@w)vDEHmkmXBU2uH%FVSo-AX(721fq{tzP&jy&jN?}4Hlq0W{c#5(g+F6B; zes*1ZWWq;iCPgz;2|EYjgYc>>kEVT8Xbfd3duyMk5g9lBW=I%!F{AJ0Vb%4t_b=&1 zFvuByJ@f6 zGiThASfYVXH4Xu#4imivm&JBc+4vq>4IsJ)+btGLzOt4~wVN}g0cl8_u?L0q$k2dn{8I&9!c3--{ zSXHnMW@NG5%>2u8sMbBfeNMwOpK??~d!ZM-!W}6{m+xS}4jZRcg*Uxqdk|uPPbUP8 zsm6|Pqi1>DqMmp(sgDjGlD02-C;K~_?LkQMHAYrlClcL z)-O`_)M9_uZ%9%Z-C5j8AB}9(jf5@X{lxAMDO+w{g)hvfya4U8=D7b?D$I{GF=VCG zhYk<$(id!f@b94ldt_c0Ku$Fg=(V6+7(_upF3_o{nH-5+MYyhNU5MN*KN=HJnB>M0 zFN~&iz<2|CHaN;713;}#;B^sOu!&6U!=C&-sU7sRu0@j}ctb_R&nm0VZ&cj+OS$cI zqYU4%3)FMyQ$yiq*53^;*xY4p$N-?ajjM4)m@WV(9Q2VNgXc<~>fIN$vO{$v*OZXIo+GHHSbPkDit$H|qxt+^4;4>AEhe+aoaM{Tm!P*ppakqUQ zl0}GhbdV(NQ9ZxV*|#-<%R+Rji*7uTD8(QG%x-v?c{>!~#LU{<{>Nq%@OX&;hHbaZ z7Zg06bm?6(Nc94%mH(?cbU0IK0A`Z8;Ca00c)n2_u}-+)Bx36Y3jRNco9p}8;l^e$ z9N}gS$P9m^81ZQ(Z|e*T(~yEftU|;371GP(9%=u;P=)|2)Z-vOP~=UCwo`9Ajby zWOD@iUMpH=rLcdpa5JU}I}H&sJR#C{9Jp&2+4cA<%l(3~3^|iJV;wI3&4T82IUZ}2 z$GFY*<;?If=Wmb70y(zNd_BqG2z(tyi5$;eJ+`~|HRQw7AoQp#QiIR}YY+;PFLGT5 zEn!A6CRFYzgyqP>&lLuenpAzd_FO&%Co3m((A@ZzMsw@d7UEb%$j7-AzKHxLL2{-! z*&kMy4Ybz-QJblgP>~8HD2k(c$Bf9c?mv1=BLI?5dunCQOy|+)P_&cWJAjG9*c5#h zx3t_tDxsWn26b77p3)GD``-o|V@EU(>*gqrOIa9PJF@!sCu}kTR3?iEp zjGIn~{fvofaCVx+IGj1OT&Us;e=X6_IS4Em#DXNPpi#YL`xAl&QTlvp8BVFGA}*e= zHu`G;YQE-vte?j*wnKgzd!g1%$NHxELCF0#T7%H_$fo~=GR*U!iL6frF?SNO&h`n-7#zch#Wqjp1WQ;#B8h z%k|W`>1z>ODzLr%yt`5VAgvD-RriV3X4R~6_nX}{Gf?>7=rEtG@v~MSU{b`>%I;zz z3H*e_G%EwX-ROtyJ}gI+1?(}+(Iqo2|-0|Iu0rb#csy?X#BRP=aJ z`BbC2jeAEfDR8A8c?_yIpA_5RB+zvl1mNT8^)xwEj0Z2!1XojE+fPDs5n_{d<11W| z+zF)7QcyH9NPps9Wxp1FKBxatgxi-VNcV=noPf)(#Qko^*Dy8{PNs^apMWq!{lGmgzgwGV_y=U9r z@j^!QB-cAyyGN7`g|$}-NCF{jTy07u-LkP&DgO57kLo#w{Dy7r2&lu%*saG!BkuR` z4tq7{4W=+DGd8-1fEoNYf4uTM)|t)T3Te69ypPk>Q|SsuB%X>CTc5O|la2IwP}0F< zIfK8NM0?rs_{_>6Q5j{d$lb1_tc<7m47=yWqa#f}?Zb9pky-Ch_@in3^fjcKq>J`!T0-Rj@zy&U1V!9R=pk_hKKr zhP$)1^>r3;OY$?T60O5-v@C=G&o1lraubTV<#=M4k$veJV`?t3lmI%e|4Co0<04KO z-=P>QUa9L-%mdTKCWc$|pljvqBvRiH_;St*mYv>J+!ki+4OL|?l3W0GlU!DjYjBA@ zIF%n%v=1#;(uviBswMpO6pjPQAgv zP{W7i`mI=~OP-Z265tajwy3j~@{neWsYsIS;-U|zJ{=8aPiH=k8Nyi`d81A<10j0+mK(Keap-!0Y{$jR zEKlG5%fSE=3Livb3zplTw{B>2(wgr`FLr{ri3j}|)9qW<%0*;%jPn(5T6@PORl?mP ztyyjtQ@w|nM*6=H`v}!4FXZDb^yi@HhS2l=`}T1?L`7g^3JsO>wT(H}i?Z}pd~gow zW*%@l%x`39epzy?#?IL*y3Vs)sgm}7z+zf2upOK3n3jZj#sO3bZ25nPZ-wj0eIlmS z#?U+HVjx^d#ST}X{?&Ejq^P-87DnT=!U8FPTdK@pR+r0xE=k?1-!px7TVyB?&SCgxfS2_r4sj&aU#Js#m8@}u)CV*v@dy8) zp|LT4Z_57(uu_8W1Mg8seY64QtCbXgpUEU)j_fP+6P`KWm?<@;132m8x)F+A{RwA?+iG%XnDiJ3hFe5!_lw&IP7m?JKn;9I^MBB`|k8o{g8eVmMgI%j&FYucXfHoCt6D}+?#4L+?15` zmrqCva2m$gx3>j)GY}t{J;HNF8DYh}>l}VqN*5-EQ=2=#=CfgbOGdFTL@RLIAGI9`Qj={e z){e%N;;6Xqub3kdsc76|@Q78q2`q}clf4Hn=a@OEg7yv+|1teIB=E1s@M_9Yj?gVI zm+`r@FB8VueJ9?j^`dteHEH~CfN~Npy~~5-^LQ$S?~hQExS$fkOjz5CGT415|3AXs zMxYg(=Oa*WDV?yNU&fbpw!iM$bs-joLDND}3`#Ak$iL=gOOp$yMA5X0a7OylWMzN* zq||WNW(M>!c%|0PECMVIDw$Y=&@>#nk>EZfUn^gTmsKXrE|n9A2_EtX}Bz_&YL^I_(Cx-2BIA4-(o@rfM~XYNYmv& zxoR6bc~r6Ok|;&}xF(1s{Gi581%a7kxH)7PNcf%^>=uqq;Y1)cx^+qF>ceZOtR_IG zC(htvF%}vHOR0MvpfOm*bH~$lp}i};S($E^=6c!Fy~Cu`V@WNsd@8j`Q)zzb(ME)~ zd7;MJCHi;>)23twQ=LNgo{Y{R8oFj?y*;EXINtNxyzy4T8>%RATS*8;OG1VBB7*W=4n)I(Z!6gq(4)j{;9>}prxZ?=nJFu8P8C7y|Pm(ATUfBiLwA$NUxWJpLM;?AHcFg1rgWR^PwNWns!k{9J zsbSej`-TE?rC;W4hgPW)Mr?zLrAMw2qD-PGXb!dL_O{c?$rJM&1a_Wn*KA?S#)&t& z;C`@Y_M|@Y0TIVs9z2|HkHBSCXuaP1PcLW|P)#R&c3iDrU7s46%XCZ+6{$WN{8M_; zd+Mi$9;6~m!W^aX(_tx}!AFbW%L|UBj@EuZ6zpl6zah*79N^LXIN;?jV zPP7J&XXNg3S=Q(Qy`}4$7Zmnuqs#5Vm1Bdip6o-L(Y(-Wm1PCkNm=G4`9~0~!)pJ@ zxlEzmIy!yIg>0Q6EE=*odl`5Tj)RZ$!wZg{*1H(JAM%2GD*lL7B7eiyW$HTk2Q4*+`}-k-CY;YMV_vkS%OyQ6*{c5p9ah$a!Scyr z0PyZW;1MYyxf9YSxk2fPqim9u(QDTe@omPU)pP2G!$Is1`ho*Dv$K5sw50%>g}~S@ zpc;Khp{2Cufts|kkAainl@TNexcyl^bhC>{H$7O5=!q^Ys>8V%!I`9%y?ily7|lf> zr~mxX#0n<7z0KX($=L4M@|0~o^T|s$%|b%8NGYT${vSFpa%8Ri5T~}XPIZY-+=z&+ zeCZp!<*@~(5x8f*7W6+B4`N03eNC>I=Qx328&d7pQd>GfrAmDzOPph~ucZkXPkx>G zB{+8jSCkCf+Q=fWt`G`D_H++^<2wRv=8=t!KU6ZzjtcyO=&H}4`ZQgY6 z@qU08LlCps`>6LZ ze08^1pbwT$(<5m~*)1m?9#xE?l8=oV6zsEQjz#}3cwu2JCK52`UF%N}{e;&74#FT! z97>mD=?NFA0MrXspu|rNT6(G;6r8DD^}Dnz(a(}U4K`^t>;#BTnZ}ZFe_OBb3&s3w znF9wcCgX9#FOwl={;*eO9)4~z@@P~pGJ^TOkr->gR9gfIe#|yuk1WuM--u7s9ixe} z3d!8`3lEZ}vm7Z98(Nj%Ex4Fdt3m6EDB`nNMK~*uv(>Qn6GOF?6hu0GfN-+=05H*) z#9Vc89JxFA2Urd$sVlIs%gRltdM9n@q>pAq zy!_yS;}?eB#_v8^p_XUl0RM5O*qXt#TQ<@(^r$cDcQC{2kJ7;27IT zUVAc(`Qz;DX!6PhmSbzlcZm@*LvwVnU1_^k9B1mt-WW8>s-v7+7@qG5NR+@qR zzOG8?2N7Q%o2jxz=P~M!k9V>H{U4P}7c0;qx(%!9rCA&ntgIu(nQ;jbzsO{laDUtZ z(agnIZXHa%IRQ)Wjz25^@oDuIqKpr2e?MxHBRaN@r0b!qlE>K z@eR!MtRLBsq05;~OuAYrl|M2thK%1D@}Len$XXIurlT+ScuW*Qc{`Jc5LrDHrw=Wy zd*r^LqY_WL|A^27ARjFNgQFNU^7bEq<7QXDmULZ)Z6yJ-=Ai0|3x=eoe;>b?t94Jl zK)s6ZSUGk)rixaEmrwMwJ;XD}XPEcci^T7cD8bTnqwz2AY?Ce~_e09u2;Y|tpAXNU zp!y#4DC$^UjB54rLnQaSP8yf@Lg_PFCa1R#IHq?&Vl=u(T5xItTcpT{WY(i(JylM^ zUqC2WMLcXvM`@lOOjlyY2QNqe5#(H&hi&mirWJp9cLbe2uXc_4c@vu=QwaK&&ivIq zx$#YW9&aVmqC5tX<9N#0)M3AVSaR%-H#e|mfuza6K5fZ;l*9jWUdwHauS1X%c?B7Q zMnY_$UPR0E*oV6TT0jihLOa$+B(gj5t9ObG+a^RYw#cj9lAbxYR%%6_9uOI$0vsF~ zS~=5~klb}onjgJBertMD^kj;AQk&3M$OJ38*CD$$)$)9?y#r@_rB_W@z|fjy2C}X+ zqZpwGBr^F*9u-o##cC0 zeN;AFimB2B6Db{*Y1qcB3V2PZORdQFfPP#gN??Fh69I%l9_DeRCxXFAf13nwq~dE-{ddYLtECM zy4KK{iaI~jimISeJ5#viJp2+fWe@ZeF7wC5(gsriSfDsTCVjU=-Rwsvx-WMS-7t9 z*ePfRx&2lcTuNKZ&_Du{(xNdk_tx!X;VXiJ9y>e^GrZSVwfN+q^dBoDdGKy*Yr*#s zc#CzoE2rP`xx-VkT0P0meUg=qOP~x}bgUH6ts~HKpy~t_%uvkaUy?0>U=pJpHXE7ONG(V%~&I z=^mrL`$Ms9-L(;Z4);gardsb8)5Y~rvx%iTh2xkU(?OEs`kpgShnWcbvhqF0%c9T9iloIW9Bwb?*Byaktr1j}G5 zH7L&#FF8&FKv3HTmO!W4zpw^PI3mG9+bf7cH5)}OxlWf97=^Z_F){XGF$}yLUt_M< z?vQzNlqSxir*or5U3A4xaH9j`Qiq*ZSnGA>o43z!u`0Vmc0y$Vb2iL|<%q@U446gO zKbpy?#iFc8SC`SYwU$jwIcF?Qqnytu#6U8HZ5*hi_4oQu(qkDf;+n_0x_|L7~q^x znm@}-%CBj})#|Yp*!97llv4d^m7ke0&C^e}6w`6*NEsliA=b(K3s3JmX208mf(jd1 zcgI{4@iR?^iCKS}bnDvk$97h|6Ql67Xw^OB1#YfINw?ltq#mm`Kp8p6;ApB=@QU)q zZN9FTue*AfJ?YB^j>QA+K*hCQP(pf*KzWVo3E@|3j<#NQR6aI6#tsj_l<4i7*dhgO zN*$=Mu!;Gt4(|e{839(l?q0z1uk)`jXNO#kQ7iH(m#7cjxEfa@=U(yX@j}Cqm_rc7 z*H^18rUQAjPjkS!e3lmVW%%%sd?2H8(81*dl0g9YJVSkSg)>UYH`9{9y$qa;5D@*} zE0^VO8xdt)K?>}^HF$K-$u2rRmj}6gaw5=C&}c7Lo||8k1KU?hG9U9ul!WS!s3f;P z3Om>GMO^ev?PNe4rf+Rc$bL@&-Sc?FWb(#-(=?gNhHwCj$Pf0T%MDEe8M!^=iZtGxO7N#i;C$gk|jR!t& z>$!!0gp+x!V0D1^aKXqQEzfbdK$6aUDT`_o>o3}MVJ14o@{zKj+}$l}=bwl;<0^B) zN!tDZL4pTH$8uUsisTp(C@Bpu1M^|&Wd8VBd&*BarXc1Ssl>PlO6-#3LEKL9OqQ|Y z28N1hNmr%%{+IW{RhiThZR@qGCa%0iL*B zr;$wBxQ-lvvvYYs;|@B?qqUkMJ=-dIp3bJ6fL?0_x>1!-x~gqqDB^ zCS>M)W!v@^g?qq(#ek{7`P<$v^$s_S1tJ~DYY~f}H_P(TrMu0vvL|#l0ONi+DNobj6c=D1K0001qyjT-reZA=uTWz z=YepK`f7GvNfgGzV_U}>@*^_Ybarz8sm!YD^5ezqglbZZ+lPO0g5vW-zQiy|MIQA#kUc5hlhG-b)aAdVaNnULRBQ$ICafP ze_PPhvH%wScCWmqt+Omy-U}pl3{Dr+)GMHk^8i^)caK>Mt*E1Hds6~lM9FX8GC!te z0qt9SzYHt1i1}p_gU0XG{`IX(c-R1lZ#^kp^1=>%|9IrMuFpoFBvX}tyOls|1n#yJ z{Ubt1PPlY+1x!easZf0l)9TCLhxhg@b1W^s&6n1#Pj7v&oLLY$z`d%h&34Y@Iz;R) zF^YAo74r0cH(#}xB0ZNTDD#2qj_V@190p#rJvLKqdh7xW;Y(0jd|GWrFV_W(jU~2O zDZ0#O=PhlogZj|j70uk=Pu?rYt1av`cj85bRhohhK(uf)tqU2Nc#b&rF|1H9kXS}` z#(Iel9 z?1cLl-CwR?!qF;J2#;jz@Mb3o5~pBV=7%TLmJi1IgyK6`I;;x(8BOQGZe8k-k9cOi zp?Q!!z)ivoN6T(Aw!wTPV017Zf~sMV%axZ*8Bj?7S4fSWvU^l)noj$r$imVvk-ltJ z?t1nv<2lVS?ZWAZs<^BN1siBu?ErMT&ZlE&kr1QeiOT})spUnGmcwfd1t@8v4lHriOt};;Xcb8C$p?|mE;$QwQKn2y)o7f613KR z<5s&biYbEeQcSXbS21`6knPiUXOu@ubG~yJnUS_DNEZ!_@JY#eTG2 z*fGvLO7a4W>mCCO)(=!OXQxCf`}m|R)|>E*3@s67CaW2p4fvK7bXG)d*olU7b;GJ} z!&vlY$ox=-Sd{27>~b`3cmZs^ZGS{veY>ibFa>QuCTlbT@+Xc@Y!w{%{H;GGn0<0? z3UdYLywnp#EVJ39d--ZJMm!)NrUDgfa#v!RWgTtY96IGj(R;|sC*|f#)= zww@53jp%|=7oahN*^BT!2&~sgjUO~~U~}{JdJF{^(&9O4Y*JAu0`<`LnTv@X<+Vd? z&??@=ni+K!o|<_kIW{(0kJ)UlEmqljL>^e*(wJ$)#jxn^r!dlAKZ^F~i*U#IW2TV} z=opjq_nQED@P#P#Gdw>(40M!?@mCT01jCOjH!v*A^4VsG2jW zP5Gh%JCdcvBmZaQ0uY&dgs<^eRd+U+SQnQw14<;)U4sNeQctp#6xC7}DhJIjgHk3> zrDr4mw}BHjLoOekm=+{rH{&rac(qnU}T1B^{RP;m`L#)j^;n5hsq+!W= z`{tN>6|Ec$S|uZ9`|X%N;RopumwLV_nPe+dpir=s1#Ort=~n&@=QYtSjS})JJDMQn zXJUi3ie&e*XVkzXnoxhnuG~HpT5uZFdXj}_kr^DZ+_BN@0Y#jVZT9#9{aay4PmWu< z)r5I;>o6Lf{oxzV$40l!Cfx%-fa0C*7k21o;iAq;n7Q&>G65gHMq1%`w6*9Zb=8X2yjQ*Y(v@n)BSY246ijA?l17)$2Skj z*%niB`OgBDS7Mi4aT!{4nxg2b2|3`*S?e52AFBaQIKTLdipjPAA1OmLx{MvTJOp3q zqMGE&H>G84mw;P(q}@Y(TJm^}q}bux6?vjmPo&|@$vWmIQ09G#jdtWmRyCocgNiYZ z{D2dYS?ngMypJ#~1@u-$?0V6}Y<8Lx3bDP?2>%?3#+Djmn&xFnGU$o~z8@(m_2>;YFKY}(O!k=Z&f~6(08(R*V(W?zjuQRWK6iDW zyjW7g>j4ElaP|(%$V~Y3Gc1eEUoN%Vz8{Rz5vek^QEn(nbih*$8a%QTqrxJUK=V>o zEaM4`?%KV+&eFTjuM2XTraQYj8?4D{Rwn$sx#C0KT?q_D9U=_#0w;j4`?%&b8$7SP zFH#^dV42D7*fX6Z4M_GHcnQ(Q2I2X8{_moUMl3DxH30136U}eyKQ;@u2V#m8`|C5z zm>Rlz2+`a1)I$=Q6ABdxGX#U4_iLQ%1<*_=AcA#4>7Q;IFWa_Uj-EtJyyWrp?Bo;A z4V?YP1y{0&IpmH<|J+OW>N1$T>U!67ib<$@QNpnCC2q~=T8dDt>%xi(*%)=F7yrd* z)?Fj8uL&dF;;OKc)7FAl$c4f&zzZ`OrpEWGusyD|p}q?-CabZh^wF=_K>$2CYp_MJ zlv9Nzd$>9bA|)Mgc5b$Wbe-d7Y}BvxdSG%cE}lEY0odJR8cxsg$IvD;y!qXS@`2M> ztWdQ#;>W(bmsPh2m501z*90wFK!|@!{_UH9tp1;3OFFiVM+$CBN^>ZlNS}xbUyj5X?^C82`@kX;5u}3Ch4`Z~+sr3AIs?)i&sT zNBh8P+_g9?H(ya0=dsJ1KUS2(bKw*Zh1@7ryAEANi`R3UjLkVEij}|&CKE(jZz~-d zUeiT0Bk1Tydd!)G4S2o01u zo~=Vua_#$uL`Vbo22YOu4I%`9uVwqGl|BxH99km*uNp>M_Ies?)K2X&b0ZUky@Mt0 zawV`!L9aXSXym&w7-Gw`&{1H>Z{Eo-)PQCI>&!;n zF(`Ts#P@pqYyA-a0n9|Asq&;6|i z^PaVsgY*|nq(AWM6#Xtiz&eazeF{`;byD1; zy)Q^HUV{5ULU2GF@U20tUicbT)69m{(IwEufusiumL7P0mnnq^N(dX?;61*p;>%?* zv`u_U#m(l{~E;v3}HcH@^b1j`=pmgi?OmL!RR;b+16m# zD|->C%o+0P`TZ$+xXuI@+}CJt;bkgoNdFqq$oi&FKm&tAA=ELvDdhiwj-U4oIyOFA zp~&R4*Jqi!x7sbYjMH<(Mg_q=oNQ%Zey^8^bji=OUvNF$+zJ;l4?xyGM#=Ap2+gK{ zP^yP$TJ@-^=sYSGLTP<1C!J7S<@Gl~hY|YpGH;YiNUHC|m~&<22Rgb)R7qH=Z?T?M z-lh(TW%cveTbxPdRMXrq>KLbaZN=u%6?JDop+Liy??HtcidCUr^QQYVKHam)yr?D{ zWnUQWGzA)-vV(-}Xlj(eg5(TiX15c=Snn570N&50k)sjg`KTpeue7(+eFIDSE3@dxdH~8t0hnsjPh}sZfm_NXdd=jHPzQ<;XG&(D1tSbfD4}ruECh;CuOMA zB=<-K;MoJhLZvOH>iZly-2z+wDmHE~V2Ahl5LZ9wnN~qvpc{b>@j^;sK3o#Wadqs# zI10nyA$}WPt(B*koNOivw?=Ox^L$snO-lct3-ZLct;U-wA?44V4GCeRg5UU;dp&2v z`yZ7VY=9f=QVgf^3pUH?&kWoKOn8JkurC#4)OBCi#!_E`{FG@beU6irzN~7gCsCH; zoA?y^+fB#?*aX*QK(rAJ^%dNgW+upT=)!D3q-|iwPpGq1y>NITLozH7P=bF|`m-;J zr}O<9KH`#f$5?!$@g9@$JCfw>-zC;UW0&RJfMfl#fw}OcT`LyW)XtCf| zfyno7o`7p9*xG$T44AiD3|xmWVE6Dswt73|6fOV15|YJS`HEzd$Xh;1_1&%-;tV4$ zA}fLOg@EysC~Mf$YPfK zfv*(rCm69S~N7cn9J6ES$|A~Z6Bv^F23!ebQ>AG3-^jZI97_8(t8mKdM%c7*lx=Lbk}h% zDM{;q1}f0B=);Gn{6(U#yUo%(=^W^J+3hWuPE(I3^;28@xbwcAMmu~uz{gVf7<8E3 zBR`r|_5ch?slfQr9UrDaCJSA;+wi(x&a3o-kzQ1w;Mt)J6uW?*40Cj9Xs?IIM%Zu# zKMSKaQitCw%E|Av6vhM+RD@NKuHe)aG;a!0v$Z;jTPX7r*@8DkO z-`+@fZ8mi(GF8tc1jEVnIpEmMTjf^mTTcGTPPc|pXd7h9C7mD{+WWDNf00Iz3WJXY zSexx6M3PaOtH&6Nur_%bu_3}S3t3Nr4HS852PRb3B~=O7mEc3bcaBY%WjGutV8(ig zg+rh%$)5O!B^KVLTqRVJ@3Cs`1?%?)b!=ADN24(U8)o#D*_a$H55Z5+D&l+CFZY=; zLc!5wfVUVy)^n%`)lbA4IaUDV3 zc|_a4-$|vMTbR}jfP`y-sY3Nm-IrcL7B8+;fV2O%v(}t#R}$q5vPlheie!6W|L2%s zVvwg->t(sjq=5-&`?5Zlb91v4a@Mp2d3Yr`IQaWSmT^EU61GQH4vmRuK9Z}U;W+~OQ_P} zffDCa?A`CVdZ#YWc?8jW>Y3riH8^A~77cG+Z!uGTqwcQPok%C%bFP89p*+rvyufgn*bO|mhd5OTbs{x0O zuy0A|g@M%DQEXqm9DwG+ofOpL{5RoaNDFo^_SE&yp#H3fTN7jAq!Zr;i!@B!W>*|+ zuiM-D(F7zDIEXo_CgH9`V77*{LN0D0Cy5J134Inuaa~L|cB#({9SK`9JSZ#X?M6ul zXNZ4D?om)mGGicktam3?+*UPjSP0bi)Std)0N|OQ^KV^Nw7Yj2obmO0XTEiixR|3U z6i|#xx8Q2L1%YT#8HguTax$fF+?ZSk#v|`rVAN8f5=OwHZgJ?~Nz5X-!B)3eGgGqJ z)DEKJdIMshXvCoO51qEKU?^}}%=~GU^;HB*m*S3ncW3&rNwS5D?{Dx~*;J9<>Wqw1 zZcCp^S<8YEkL*Tpw);bP-s9)-qKQ8d%O2KiK%&jjf|r}rrqI6O|392j7n!*P<@ zthrie;`m?q6vv|c>dcmvOETXC)tRUV0LW~%-UY+S)R&q&B3FIj`o37EMLpGW;{73} z*u`7Rn_>CEl=HJn?r12hv9cT`yxT~{moK6|HN5b$UgzuZEq<6;fhSVDJFE&qh}mtx zQ^Y>;ABqOXXRu+|`Q^SJW7~AtGB~h$s_oXf zqJ^LtxfrCaPa^*Qj!P~QNAUQE-^la*b5r9rZG)2bFPXi#_44Y$(NI z;J@Q(kb{(`Y->>X_Di8G`~-^C`A5id<1V>{d!)XgRXcP_aGZN%;;w-J2`}vxHr$t9 z_MbDUmN^<~;C$$j|dg>1eZ&y$4MXMD+=vrk&F zIBmc~&|MKRSFYh0M8`b-2*GVF=hMi@RL zbbJ*L(!-B{YUEQ{kmi3is!3%H3Av(ts$tFv4`7CRy3ZQz_SjJ;fC$Z?SqyV!t5$^T z6vernTzE`bN2FEehoo<6&iW8gd#uU8PDS%0Dpoi4F-_EF(6`gg3^Xv~>Vw0f5QJ}3a9czDnu>72*5$b&q>m_+bD1iNMxB~{ z*SuxSmIVsBm?WFLE=ce%9Zq;%Iu@UcG_H*(><`;(JMWd2TJL@jJ%7$e+J=hen0Xxd z$D8ZC%|F13JBvbU8bEzI2uf90FlfEAoGomEJGZtjVk;^IfAg8_5ftnSj2n8fw%uS}aiFf`JB5`(VU^xw(^Y?~)TYVcR9#=M zUDkTVEFMw=;mj?qNK^Wf#jJ*p=4pw}{m+cKzW(KdanBy{9`Y3{X5Qb!uI+&R3<)m& zXQjGjv@oG7&W}lw)JJ8}>$zWoq|qGMyoykZOj{prH>A%z>)&f_vwvd9zOqWzE!2JM zAzN+3#=1czf9|I7U_uNt#k8UwmZ&mePjlk0MS&4%Q;m3O$T4f_zB;TMvFa0NPz9OR z>F+6E5<9uemROa z`giQJvhBQq+1aj^*W{Hy17$oYT?yEgYuavcA=8L>$6B%}m-IUS9LV@*>cex-1q_`4 zPWQnijq~kUJ=LOKw15HPnjlEwyt?xvodmM|n!>B?6~6Ze&vmn4MZpWV1sbjC7Qj7K zo>Sh>W!f`+6+Zv~Iqrm=53hUj+|cE6Zbf`)P__^lD=9`GG_kS`Dj7c&*U|c}SFYNp zFLc%V{CY;b6qKhb;O@~6OfDpcMtBe48uQbb-{bu3d&NjoK`|eye|Vj9{edqp=x zPx2ljoF)o@_&_wAfbOSR7}t+y!wA*yH>7o{T*XZV@|Q7h0c(D59XGH|rOgl{SC#4AhNJM7Lz)%S zOd*>=e5k)5XVzYGFKGGPdw~^=e4+u!Hb+3>U7IJ9ejNa07jp+jPpn)oOEm-0a8ysre=}O1iaB(U#t)wF!R^X z)Mv?vWVaFNP%%#`pa_%B07)qo|I{Uq$=CK6?ih|`tS8~Hs^8N^@}0VwgW8&?LMEPu<;>$0Z%!-J+3;m$T8#SX!rUraR zF>v_QHiU$`7rge<)!bHvgJz0y(tMx`E#p&kKrhN|O3q%8ExS+Pf#6t$XxuR<(LL`B zBT=zl9t3c&;=SFqO`xdL9HXe-FrSLYL{T_0&`VbV#;}NR=pcC)_ z=%I`;EifsS8va>8c0AIP?tJJJ$Jh9><%Ug2%)sn!wWJuMgNz3+zN{OU~p(($y^G=t; z|4NIkQ;dK`C>QE#sms|GeKl2iD}zhvrcT7qPBU~U(l4u#+3IF*7*I%H09L}w%#I>HAH>%8U_XSm(+eSh;|*pg2c&>a9HN8&wcWjRmpYoQOuQn`;!alC zZhZlSnL58(pqkbu8%>fd$KGGLop*q%V4$rKib;jqE^BFuEJtiKBIXbes5TV{nKmHSfa{h73K6-SZN|b+M+X4C3K8=_-Ie@Yzg2`K@$#q@` z+g=l^Y7B+czMEofDto5_P6i^Db%pGRVr-wj@=5u7geUJZXldN7rgCGez2nOySc9nh z(wR7t+r5a8`rWq7Ngawyjw-mg%S9Mt@vOyrr)?m=2ylDYejwu0!Ss_Fti$Oi=r6u+ z0D>y-*Nl?JK(74JKfZ1$Hfyfhh>eLwxIIG{Sa_uD_iU?KQ6`X zuBo527Eg3$f2zJ&Fqn@f}A*2811S(~!Zuy#-9h1%NOLASnyo%Js#C_IiLF0wiShOGk+GH_mZ0KHms@9rkN>IVQjE&89}cGKkWaUSjBBmLnwUFlsum0YV>LH77_AMGr8VeS zamlb8m;PDIus!SO*#^4aX3!zzuV-&u^7h6=IgYf`lX}dZ!KnR568n~jd!D6>kZsUa z$>@c3%5z52ynVkJhOUUVHn=|L98(;3*tfarcIK4o14H`XTe_mk$P$`LtPE4i?dUdf zo7C`_QA{uBEky~wxyZ~P;vr+oGW`vDOIL^fP%FqLw!{_BS@yAjODmwP(&VJW``*QU ztfc|*@tW*0nX++?sGNp6vT5dZb!F^b=z-cuU;qpg*0 zRQ1yPEELSGIl{pOo-nME#o~Le$J|MM+Al{WO1jNSxxRn_N!CCTkT%-#tenS%k~%+9gl^b?e!kFD+G@Uo2YV*TVr13f^n zO9Tf~cIwl$Hi?GOahzK!wna*T0$1&7Ux^w&E6)aGRp0t0%4b6+MENE!ibR!0MQ&Mu zsu0p&gAi!eEq$L^x?}egU?jK+_Y5xTN}t^G%2W4?P2rM#uL%F>hGX;T^iB1gbxn z%R8YkIf9N;*XOP>lKmTz&~gHuC@pYGmyoHjkVu} zx0{Eh-fA~|9X-|YB&Dm#j2^n+kJc{!IOhMslFVc!0|k*BO1t4uU_ZNp45VReh z!ChW1djz6pU(Oi$pYXXwq%;{Q)eo0x){cjAK-DN9%=OLSxbsgJea}ENcv=nlJjr@g z?#%8N!f9(fdDU_w_r8TYPeC~V8;Z zC(HLyqmI+WK6oT-XUyQO9TTv&XW>p1^&1x|jt9DPC@nbS#=GAU;g%bE5sgnH7GG@K zc@@shY@IZJE0oA+9Gc#CmL-68od>nLg}nIjNCkI>9jD2`>|=R16OIl3^({JNWkl~0 zOCO5fmt1}*4TBijm=)qDeOQ~-FRTG}y6}yH+Knu>isK0D(*8iOb)P`*M7#9p- zn(uc34;=xLzrj~io}Eb!RAB(jJ0j1!r!;3}9kmwyJt$idu$;=q>C?dc#%Euy>&(%r z{GOM3y1Dc!y&4-JkCRD(qkzr<2$ma43bDXXFt^7bjJR)LgT>)=b+OkH$%j$YSm|`X zU|`82@#&1mj_7&t<__hPaLkH&tZs=F@@m|5h(Ykfy{&MJ1Z-*Mrg2R#KW8l8R>?ga zfxMgY!2rt?o;c~ILd5x&Nq^1QG^qD4VXUj~-Sdz`mJ%9{Q)$Gl&D7gNB0iEff!Q=~ znbHuHa7H)eyPTaMnIr-z*$Tr@j{&ldX7H=_0{0V5V^-NUMkwsR8+jBe_c`kqVq9-I zUTo~Zk&eXJ_w$710^JW{zR;jKd+20c$tca42etd{@d|&MzQ0e&lnq~(&xvBGby=gD zzOjGFHD&nAGjKY{*=U!pS*%MQvkzIcf2rBg*Q2?sk()uwL3b<#gx}B?7fv?ta@#6=jNA${xQ{HOAQgVE}C;a1F|RfUm{;x*0DOR>7ot#q`J>9^<`w= z0Mw@AB^*0kT0>|+g~U{(b|N#y=$&M7nPE535NoPr^@vPe*D!A$j3nOtsZ{2N)&fKR z1srcurrq)WpUc?fQsu*GNUH#`b{B0aP3s3$x3&x*Rr|Ch%k4@sEM_m$jtB>jq5I9} zu_6&EPjZ}2Fh(lqcQ|prsz>8GSKLin6j6Q1WX$1Hq9Vr~PWT%%FDW=%gm9$}_#D=R z?0u?khq-d#m8v5x*LoQGN9Uk-ZLp{R>#_z9v4zMCIjl2(tt#YxWjPmCY6MbZTHP}B zVSU+fla=Oeej*Xpbz?uznI34Y7p%FljBdf?Jx+OuV_}SjV{2~oH4?Z-2C*Bpo61qi zF(e*oooP&&i|=zuv5d67SAb;K~|4g8$Rt#j&?xWM4VoRJ*xLxmpoMHj|z> zLNaYa92?9Vmqx%s0|-N#MCys@YT^>-c`XvCerv6VG+fu*3i_T0%W(Fh?e))7FZD_T zsFnfISR8QLOHPBZ+6?F`P@Iku&(Qe|YxsU%5`ZYD*nW)xgVv^g?p@Vl>puI~TzU(1E_mBaO=!GHyI7)H= zc!Z|Vsr7Yd2Ldj3y$~vi|nUzfy=)T=nH52eiYJ*0Om`SAv-X%=w$4CV0(#(LLQ_Ed)7iPklO+@)YasXWOK+ zB=Wvg>*X&3$Y4`?4+!-7^9kI?7UpkbBHe0UT`JA)u6jre>kqwpJ{IH=X3b~>tS%IA z^twLP$n4k3ZnD{!u}pGF3WX2LjH?>t-obZDfl1}WqAc8{y39_ylN;F-&S#kW+QUtW za4{Qv*{Wkwm3cD-B{czTkOj?{SyyIp7k}e<*nEU?E#zCWmrkLrJn(NFsRYhUIJFQo zvR7x3d~|-VVU3Z(6i%pGm4CI{L==TjUbE-ORg8o`ZV)5KZ%yKs)$C(nWk-?p%a(ipl69o^AciUkeHx9*grM@|AQRUVBPhY&~gWy|eU&Y?ry zagHFV>f&t5@&r#3A}VNn>EUqz2?nN8YdLU_s3)4?MtsV2ad`r#qF2By@+-?0*T+uz z{X7?w2gl zzh)d`wK(4}Dmw9c6(9zE(3}*C=8tOVxjHv32EODTkCQ%%ZZ8jiAGj1bO5mOj@T0Y& zA*?`0oO4hsdEfT!i&0 z>JF$*Dy|8)_dv`d#3|>U&vGgz%SE`@d!i-y`ZSh%pNMa~v((uYivh&S<_*i|AyU~E z)1!l>I;$~4a0FoqI0v*u&45bz@c#Wnj#8mmJ+^UIhS{gmi9+%FWyYptC(}9EgV7(v z1nOp>9P+;y`$L?|dnsevf>G<`P|#2Q52g1rV`^nUbVO!88lInnW%OE+2usZ2yK1n$ zcSsy+!BJ9X4m}Nqa4)VHyMUkGg6?Efnjw_g0jBJBrH7b`T)=CMXXH1O-Zv!Kv< zOLx^T=nos`8N}Yv&CiJsG&vhMqMDi7Md#u)Z^N$h6nHz((jul$a}YC2PlTD zz{gQEa^)rs6)@P&sqgHueC~HE4+r_asmU^H@I3#tqKboAlbE%a_*#kd`GT0#sYrRh~`wWbN^-o$vxb z;+_i?zdHg6dn0E&ZdmZ0He=6~)FNNx2gZz5(Gp(tfXn|BJQ{1Uu6g{FV>tw4t4!A~ zf)&-ShZyFT3<7vH>5o{X+YfgN31Q#OzcDno^qK+;0t>Z#=&^FppFSG;u|$vv=hL2f zT=CkjB?Yp3_WzEDc|u{d;V&V1<;}6?de$0bmBT;8fm`Wp|K>S*zeTsM`L86=3FGpA ziOc?g+!K#8-0;2tdY{v0v9(UvYVD@4U$s6qa*=z*o|b;jDE+^j^j_jjOuUc8*}Og~#;qOEytbY1`?<^{6IJHYhWef>L9 z+c^+`;|{fVG25PRJE%KLS)3}N8$t$9Mn!U24A4`{7oaZ%D@qxN@EYlrG&UHDkY?mq zb8HeR@g@mNdIroqOoxPBC4ss0dek(+aWnotl-QBER9jIOU(dlxk=$*2qgLs-*kdnv z%$8m${-ds-EOtJBywFD0en9n?X1~D9D*3En23krq_Rfd&;Udj=G%$sSS)}czgF`bE zj@Zwawi_BEpzf(S1^2Xw^SkZ!^(b6G`C;(*wJB+6N2YzNY#gi1TY|~^DyuK&Yuoej zT4w%U_oAEST|AL&8{X31;|DD`$qN+=GbbY zQMm-|C*UXR4!S@5FnS{z-2*vvvX}N-_9>5Hpy}=MNhE@nram%}gP56i5&6#CXhA>u3LLi0z7%$dOJaFZOxSz)4 z|BfBuaZYE>Q>Aa)o_dAS?cRdfQp!6AQj>x(2kHY2{2n0^cQ0hc5W0L;g*~e^&v6bT zWgAdOw&@|2_+`vVl0|Rj=SOgEtizzdl8S*lFhHj`9VdP%AQ`(NUH;p@7S1E_^9u@P zrNl5JfbEKVpr}I~Nb)tB;xYV#kMlpos`4Py5Y8hltQOQl#8#G|Vf*9-HV(&hk!7w> zoQhm{{8z6}MH_w^pV;g&lA^Sl2$0%7$-h$V*sA0WGY)2IpLB>KOJo&BzPP>}a6htx z`3{o14K`$U8_x`xRYAhb1eOHnv35dF|I4q8$v5R?>FzR3ic@Y!Q*epT%`Ro!FX3)t zLU7A^7(bHfWv+Ml(2Opocdmq0-l8nC;e?#D=I9hRtmO^#R9XP81cdg>PI?B&OPt^6 z9mNoA(FTgOH*?r)wkkK-&HG-DFCBEFAM#CWhz|l?rl8kS4WoJByp(y zqf~@?Ya~rPvE;a|(>+!#RvTzu)>g#c>zwi-wF)zttAoyQjudSuee^&qLN!t_tDAlT z9m?sdIgd&?$4)Bm+RGT6Xcjr01bO(23Eb9(s-V#@;-(bz=bv4~t&7C>Twnc(L&yLV zt#2S~!@W(%LrWzDVdFdLhJfk^#VI>_QA(V~S^G8|kOH1*zt9S50;jWVty^4W^I65R zSq94oWc7IRI%~G=J)*Mk+m6P$|M%!l4bMj5bHATljwf!oclmP146a(Migw#}BDR^# z!-%`?+rhc(5zaRmrEHN8{>Z|(R&?8OI!-0)Qr;T#vZl0$Gk|8=@rMOSm$c4kCd(Vj z2z>xJP&Ca8_ryYtypXTc7H^$^Uj9pzw-i?ky)WNvDx)YGC2G0@Nct2S%zfo?UVr^}Uo1w(%9Z{IO!;``>UYPNs=dmqIY1VUUt}~X56o~O@P`{_P zJc>(j#F&US#{Ahf^~{WQ6XM)0Fh&?^pl&5tUzGFW0FZ|^?g6I}CE9?VBvfqvUD?Z( z@slWs{fS+$ry)^o79jDg2FR+twA9FUtOh|7`f$6oN3U&uak(jhBj-Kw7c-!{rV;JA z{CYD26`?$0bGhQ6#WtOAzjap55bqx8xJuBDFV4|^hO5(r;lD*|qXN+kV)pQl@%}UI z7WL|s5W2C+-==&^ytn^k;IG;Qnq^+KSrJ#HdSa3v!y~u*FUR;~z=&E_0>+POQVlpf zNa!rV6mH@hlTtRxD=0asg7F=6ERj~2JlR$%g#OYnDFk+Ic=8T#)Gq;xdiT3YwZGa9 zks^e!-~>p5OY*}y73osS#h+JIRzMU``vJD*?HFM1s<58+7hO+tgoi?y%juA4(PI4p zh=PCTF!G9{AhHHD0M2%gT_y!KabIzSoRBte8ks*mfhss0P$BN8NXFXHQAhvju1JD4 z{r}aE{^r`AeS7BeMp$FAsJonMK$CrYV$ZR>b@J=${7eUYVZt-!a5O$0>(HrMJhB+X z5_Pv}PZxUs9RvhnHwv!pF?8=dA)c2A%mr*#4d?}|l;ldkbuC|%6zrRghw zk%AIj@Hb`%jR8~gnOv&=LBUWdL4Qy!r!jLHRHb5Tl|2H|S~+mitPoQGTA&@49P@H7 zAAl`uDnOO5loYE-bdfSbh8UmG3-EuKG%5*hz+ctLeLZ>r3#>Lu6zf+P{1hPe^z-JYuq(te z-;tXV<&a_;risdJVy@caLS_=ntyZ5JBQaMSMV16p_v?YH!M_LST;f0>s@qH*7H;2# zw-hV__Nxhr_+~O0^=ZZ9b~!lMn(mLNbi90;(6$%fCbE=v}2o7 zOBF3Ld*dlfm1J}hdgc_wc|4K85+hK$Ig^LF{lO`_$p~=6o|gV);TZae!?AlTD%Li%pU8jHU5#+$@T|eW8v&6+*aHk z;i7{zshiqZ@4iGM*3i*Zp~c%*pn)Slf%fvapdQJnYfZMt-LAdu&o$ahW@(y6p2iwW z_+2!M)h^%bbuX;<)4wx<=o_Z9-r6A<6yVrzLzs5)aL&o+#UnEaNLEt}>`s>*Cz*lR z2Oy5zd7GSG1vY-R+*$I1kyafnwx52Ev@2mu@lORQQYAmG{pM5et;zEw>hH@9-n^cn zfc2!#$13wXuM|Ht33Z^1=G!PZNgily>YPO~Xq58o%7A8P_-H~jIN@-kZdswwyJ{Mt zNp}87QdxpbRx7Ycc$Y|Yv7f-cC+U500K>4eZqB1?aTp<)xp^n9*#(nEPXDr%biT39 z+?Dn8he(jLI08MEODbo zMho8m{nK_szGK`OxgX39q2{dqb&@f`qmqJKPC1VqgxMYS|56d{J-F6gu!vj!l+_t8#L8ZS5U|*CZ$f{9HhK0RWsopSzCF z`ndtZjv_K-TfFc8ZsO<>PFtDSgoh9%)j09*3F>MGemwU~?&xri_l$rC=dFKFZ>>Qt zJ1EV`UZAlhU`vNa@oc`B^waSz}0@=uR?z>kB^Ke)}C``JXkN5mx# z=P9#?yj`%b&`C0*r^GhBb;4a|B?2b9W=LeRtieq`n7W0`W-nH6f*UAJO9r928P)5_ z`2xOVe=^#vvE<{y%e}fH83r%*mz7NTdFf89TAKp4BX_{z=`#eyPAio~h| zGFf^u_+Jk~tbH~~5dR0JkAOpnH3s{7;>{F?=vZ|-i+!0_5JtH1=o;)80tg^Xt$gl| zY%zKWF4hes#dQAT3OSYTdjY%|Gso$+YP%#0sD`o30pr9$%@I+@*|CTBjMbTT^)l<_<$;VkZFbv z9G7C*nJcgb``iz*^3<7pVi2hG24zsE>snj#bDWoV*XfzsJ6RsdFA$IlGi{=G?6vNt zdD#i~=))s9DPzQl9p*b^jM6r2Te)hRAOEa22S;i&H)5}{ zfb$#1sAh?lCDW}HQbihoKU`~{fyi8n3MF3JoB;`2d`hb15Rc}5h{HgS+bRGT;CJ5p zkg|K?NRTy@Z3U_yKkA@Ua9sKES#7iDnnTA)DJ?tf!6;=cybKdBOO36!X3s4EXcwnM z3m{for;7F^|Jn1tNGfM z-0efT;Zjj#8475O29%Tlsr`c>?Y!hlW&@=xiez7&l*YOjWr8qb!%ePIN4(N>*1WD3 z_6MfxQ8lmGlCX^rm+Mtxdl334RCY=kmN?$7)<5_xFhp9?iMJLmOz#x%W#FCr%e1tY zHqGA=Ou|2S7o^gZ7+s-@s$%QCg2PKhwEWfNrG=8LDXGBlpZH|PnvnF{mY=<{K9axe z+J_Z6d(1&r+k7SG{*x2Cv4@z2xU|@8me0A1pZiwc2{5_OA0r=u(N;ewi0CE(1^eiD zhRpYS-o@kqKmVN^d9h}~c1LzW8w9E7*}N)1cp@TxNMY-&9Vld!bh;2Y4DGe$*U4u2%J0=yF}dYj0E04Af-=PDGK|FkP8C$ z6eSm8<7X`+heC>fV+>}ZjFNSYXC9Unx<#NoUhz|W*EmT+OHquOixoelT*WM%ma^Be z-3x$~t}%0hXRlaE{OxcASvYVik%i|cAdt_qnVjS{Ux~itS&PmVVUtmF9QYV1xev%I z>hTxChBqBLOlitra3Gp&!MWWR)mn_GOC6rDRo|y~`s*wV9PurpzDQXbgb0$13-kvo z;V!55-!F8JLvjr%7+$C_#2cWIHNb9pVJ8A_O&g+vcA01Lo8BO7a)?Hz2nD}EFaPg& z><(+x`#1X~L{tBoUf0mz6E~DLm*67;_bsMCb{>C<2P@EHIN4!RoqUC6>%cCLj2qbb88Tvkt)ww5K%%&IeGVluhI{4I z5gUpWv3m+~hEnWB^gBDWfGRVW?|DJr;MKhr+1Rn0NE|2J&GRvVP5Z*O-Vg(a_Ri~d zA)f8i40LkI>{6rVskHosLg4U!C1)@F`R*QsY~%S5eDCh|{~8hlJj}?1U-x z5`x7O4^}L8d1VbYJmn4G`1(>hldV~Sc=#`mwyZ3|1JSOCLn@YcKCX5;S{<+$OvSoa zM=pn6gXF_|tugCX;QuSxO*3q3EWUh3db zVf5eLGow)$Okw6lcLH18(^eb^(6G08M8j@+Qm6Sbll1C_ZKB4 zHaX4exT{Crrbt&s(AUaBdci$Hd8Fs1^RwRMzLD(3_C5IY+2l~aKr3RVpX&$p*93;c zl*S5CCMoPKLrMq7=q z8lN2Fb5foZ#Y+M89ZkdIQ{(`OR@~J(QG$q8Pi<8k1)_pBREzAL=>j>_3A%4 z2?jSRWVk9y;9fLKx85C{e2ve!I&1Wr%7tr5EOzaZOf&HKSnbUWWFt+Xj1f6g%C(xk zWq2N~_g498!dLJhh;XZIcTReU><1G|sKG~Yk=dh+_?$=-rDjQ^F;|wcBc|wp3~vrd zz1QyJ`Y?lcTWkAC;v})bn`x9WVBMO}6P(4}W$;s=G#M(d-FnMHjbZvqVkv5v0pNGm zRO*^9`b}uEpQ{kFnn>19fGz zZavozmqSW7>i0}M_TC;O7%#+ofXhs9YAs*HiM6W*`nuf8EB>%u_Sa8lvuf_*CV+rm z(@cU!+)ldoX{94LoO{zeGN~CRK9=zuZraY|^rhXX=>mFLRef0Vh67Prsne|GLqJR9 zfk!mp<|WSH>`Vs+2_TM0`wo}$~FOQ$Kag{e(d^rL{OM*)&Ch;KNoD4zx zkS9T>Vze3w(Vm1Mu$BcVCYej^7Vko0MMRD&_cmz&3`cE30#xGSrZv~KWdefU6$EJ@ z$-!srZYP+b>*4=QTDUFCJ%*vdsVXD=XkJMK}ya?4z z=&#XP^o&JGgYFv`an`ihzXshzM7=Gc0eD*NZ5Yw%$*!gk)n&8cKcqfr+ zky6sM-1&!!w$U>OF6*D|$XV8x>uxDpjLK5X-?e|PX1LV5dgpX5Uyrz~fF`K&WcsT) z?@taB!>Accnf@pX;8>V^2>WEN1bEDdyZZ*}8jjM=={6m22R{E5jj zn=K4XdL>GD8(dfWiVKQKwnL~dZNfjzt=_bD=kF$(w?-XN{W=Ofu}aK}Vg3Dqq%vq$ z!xF5Mm&3gcoKmBo7i};J{C>NrjThJN24jpROLv*IY zw^HH4^oY6r7K04+tigSyJ-Dz;Fxn)l;52ZNB@-QJ{1u^yyEi5UqBQh@r{zt5m@TnX zeW5G(S!*PvfwVvSdhWs`+2PeUFg>b17_n;f1`aWpWbJUyesVQ-PfYq`?ZL7?2ZiLY z=Ev92tNJSjg*x-))>j{83`j=K7)T0JQ6h3_eDQDYu^1(L?U&gN&0fi+EsP2)b!!Ob zHJCn^Iz{a@{7)qZWXccp-1nIE8H!=RvM2C7LG-mL(40WXY@-L(8pUg>{n{w8P?FK2 z$nGgSJn5|@Oum?i+LVogLXTe+3{v+&#KRDmpS~_!dgyjOWk3=Eb&qUH7+J)+z`M<7 zXr_>SRC8fV`jFHjDLW4rQarJ&3ql%X+9DpCwJp;{alp^Q*qj>GXH_{*nR|LqWqPu# zv%~p@>DAfe+`qjTr#0aq)k4^8WV7eF*r?fzQ-7MqxBRUo^z`=$9GfdFBv9g7wz@-` z%qs&?3&nwJNONR_5PiVT!6)BMu=T68AyScA%8r|{8clFVwR-83_wR;q0;y#gf|*#xt%=7y|=D0hzK0CQ`F3 zvcTXHvjj%sGL&|_IZ1;#p0MNqi}2+O4v_y(=vxK|CBW}Zhksb>7_oPWpITyw4o3Ut zwSCTzo`>u6EVrG#vwicuasVm{ckU(>qU9*!a2dfd^KIHqVepwPx-ppR-hei&$-^?V z(3`DtpcXxwI7^s4LJI5VhID12j!&cc)xV(AGwO<~K~u9QBf|@STv;JasHYDHOi4}- zu#rzKm_%Z4YD)o11CsjPh`hb0=`Ppj^jODt@8nA~8ffGGS(qOCWpD}v9aXDhOI%~+RXnNnt5SE@XmfL| zd99{9#ZPetDL6)C;g=EKLOfBK%4s3r97Z^WVhSsQWf-tHIx|NXx4*cb$>Z{R>sO-_ zlcVsy-fZcIC>sw`YA z73GN9hsSQ1!YauBJwF50`{@vc->;K2mwE5F2wUY?E%>L`x*N~6_VXh&L8e;T^xGPg zd@k!z=WYuGqzegWKxIg^He1G1(Cz8jwSqo(b zb*j&8k_1A#sFF0nUH=cZ&I^OE7J{|142}1Q9rYB~xtN0Wh_@&&m$pR$#!cw>bp7+> zQ`sXmva=ohnmw_>igUaEU#@3zuSR?gZ_YC_{;$}lvDqUZoP%EyNj|HqncMASB!c)Y zuawO;m;WSn_%f@vSkmN59Jl(h{2DzEG)bPZ#HPSE1m1viCoE;20qQ5XOx#ifE3B!1 z&|R^IYbj_6D-rtJe{W!lhI%M&cq`$!Z1vW{pM$(LF=IJ`jQI9b62eX8{vxECK#ik# ztE4D^bu*yZeOAm`{Xe4oYh4z*!w#*>RN2O3@5O}lTtw8*kFJ(c&*~I#( z1lE>zGC1ME%#v5HxSW;*e7L`(aL_PZbMrkb>_m~UzCa~{229iyfuEnE|DDo99*vQV z6D0m-D=NO(!JijgQ*hl1>FDW2-n09meAX0qpltG(y}2)f!^gv0*Cc;&9HHzv{X>Ne z?TD~}WTY!IAc&=4-osjUgwZ-V-mg3cIQjXkoQ+7&sip6vZ%6`qt<&PG9w)RWtoRt+f+}uzdIo0AQ zGlj=y5a!F947X4Z-$n4|3YNt^&d)H3hcz^g$^YCj=fSk94oEU~{oT?sr5anP`(lAu zP0+=+ULdQYoT;f36`A~JOcmYfJ!sqGiIOPW_;xW@KG)o?uS|Lgj=1yZwewLb@?VWGvX!<&N=8D}OszAOK2ipu6 z^pnL>F2!q^7MS#~|C7>CORlHCgBjn-;y?9dWiOQMVT(l_=Mxd4rk+Vio{ zTF09#x#FI%IIm?5$TR~E;~APHnrB%01+i4)|J(KHpZyu+>-z?Kn$u%d_174Ur`%X< z@JX=KU*JIDowHP2ts{`?(>^v8MP~p*k@KKgJ8gy5g&qFCHGA^MS8>QH*Rpqk-f~mU zkf|eA@s0OWOu%&70aMrngXJ0nH3ggQdC(%d~gocW^$VW?7P>5(pKh#XjPHRK4M_0p;8+@&}O7$(XLbonFzQDKDIpp zNB~DbxWAQ&!Nm+o>Wl}in zvABi!Bo1Gqr@FfNMAn0hiWvODK9EELE%@%@!+#BKM`EsohYBdbze!SO^iUUmksBHd7B|p8dM*fY#{^hf#pTwT)JGQ;Qg&h#=*k3o z>snwO*3wwyWaM0h?JGC*SUZ41(FzLmO74pX=wPNhRkB=>W`Y9n_Bpa+P(Ds3U-leT zc}?~&p3ur81@E0E84~MJ(39QIG%Mr1qXXjnhdhK-m-JR>I6vAS$NPTa7P|WOz8GD; zMD=a{ND_ROwx8}&{^3sDlWT!A5M?}`<55*$moKi)HDyYwteZsKwL+g8W(MM@T|K&& z*-)5#okFtDG$O{_s{HD#9xyXZvb7AsA8eH}eG9Lv9|6G3&H#?$AQT%nc1GU{7HjUb zkVPaqcEy;Ncn{vdx%wJzEMwMQnF<{rDr97nJGWAZaRYgWye>cEf)2o6p703tUiUAt zszN~YXpOJU2O(~6+P6aqz1-$1CL!D8R>5i#+`g&V2|RHL)^v-pI_VoP zmkZ#v6PKH8N(qfhIDUeoQ1oeDSgcoNWCL@Oh{(dMm4V#I-))?g=fX`wsIfA4cg57~ z>|v{ts%V5Y07@Z`Y-z6_|5xFvnm8PW>o_(y$dkZ44s7V9c1P|b-^rkj@zG!xhU)J_&5H^>EItc3@mwY0`sZJ>w=f{^$tWs0}&51L!`vSuA&h z++SOxNF_H;go#%Kg|}Oe5e%3Ym88zw`Mx1z9=NY zFQnyt?70F#^=zv1A7R1~Xlk?@_mpbx>3$TlaN=6O-{?#=*zWJCASY$zensQ8fO{^fFQ zZzhk3*y7*$N)?!-_7?Wr`j@Z~9(O-n61ZfaFAJrDyGY}_)pY{pQV{?tIHbYX0&*kM za98X1*QbhrfEJV!@%LURf#WJrN`P#Cn2XQ$n@E+Z-UZpMjg6=p4;8BM^lYh#s&t1A zxV;d3`p52fHBVxrZyn<%Y4br_CJ%hMP^-o44m~qFP6~H=iY??A4M|kBa%ivdW=&!g z;=|@nLKQjZwj&#`L|+ihP!?2V&rhsH=CRfKzQ|CVnDomZV7S;yGNrvXl8I9WqR_ww zwDHL5?1o>09JLF2ogAKsyU*dr>3hHw>M4*0RnhY)LAxJ|$X0P1AqMDp7HqV=RL=%B z8YK10Crxk-`QuBZ!M$Ko0Gro7P;3tu=Nh4(ox@D_LLg|>3C@!f*0>SSHV}VX-KaHW zd*I3)b9?qUc)Q++5FYu=CC)h&)9vVS;7wyoO0K_C+mp_#s!Td!wsuPX-Jxw6>IhJ8 zXJ-m|8ubxUz6B2N8Z)a2@)sFO2KU1nPbL`P)5TL^^p48HC(~2abfv0D21z= z0kx`4Pv~zZdI;T*LQfu8l7FzeCvq*8v!z3ol%agxEOfhSHf7wSc(0hFQoyXjmqN@f zU>VneK4a&_@AvaB5wv#jd``rxukAHpRU-dq!*!j#_ztbeXwW!u_L@cw&n8YCP6u(> zeG^o|CsMAniX~KL^6IdQ6`#O&RMGu@HyeD1b(Ox~EX87)2uv zv)f@tf&<4-@b^|CrL6_)jPU>e?88u6G(-KV8t4p24&T`|du{;u^f~&glu57OPp^(?p$4@f8J>m$L5_Tq1$b31Uo`qiKxB!V36rC z@50Uliul{=ir(l~qW+HG)5H-E_q7oA*5lSe}hjw9r&emT31W_WZOWD+&_KK|dButYz<$Sb^wVV$_8Z zvu-`mMyo&(u21@E0A3?j#ynF~DDP*Mrk=9&a97npL1TB#0djN(p~P_Qxc!>TR`e4PTR8g5fiPX=sHrK zoFkyW2PL*Ai17HXj3N4XrG}@xS=vq6G2edFHmLcL6!JEI6exjoBjB05kXE9dV~Uj% zlfs@Vx`d#npB$$ud61z9r~5xWGQAp}dIlpatKLv>Edbefuu^>hJQMrXeE>!TBTcQ& zipk*mwGJfmzU-yxJIShaak85Ar)IEbDLn70VgO#0gsmWePy^6Sw^Hss0E>6K1WpET z5pL9_gkeKBHvfNit$L)aUAnz96j~ZigV!xNs=S9OOH&9g$m~z{NL=5o@R9CmrzI=Y_doIu6V{ComPn;P7HLYA0z4bOXYymGL+$*eCL>cVx2+_@PiC2o!SVFqm5ic*<*9S)z znXB#f$YU7K8@+M#U_beqSB ziOmWDot#Wu$Im;m!@nAX;eE+QL$Pjsg!yCw!D?Nr(tXUk2iJz}@{~ev4s>QL8qF)* zfrq>GW+D-n1eiy%$ibxo66cgeh1`gQGJ?v@*U$vLBTA{#k+yFASpd#1*L`Pj>N^kD z`;A{mcA0jczqWsi`whFv*RZuS;3En;`RzkY4Cg3Y^6svRtn0U?B%T#|Dw$m4v3dh; zV``VkDeX^z>5n|B}d?wOG08Du#T2ijk3a?0=$|E+*7e2Dy=oM0|E2*=CroHB7c zp_zL`6Bk`AR#LxV0h zr9^VP4d6DIlPX0^DTuJ7Gs{hZKTIf;sPeRFhuuqvlrZ#xfnsj;F!NL8>(2ndY zv?{N1YC>G_xXmYL+E$?gV}ho=cmaTKZPZ3O4)|I9F11kA89^};6h1d^U<`U(F`vn8 zvi8u?i6K)Zh9j2v!@R0cliQc1jRC>J`?!G%(CkCCsX3y}fCfi!sfq}Pj#T2P@xiIx zQ$E>X*}2Q8X2VUt(ZIiuBBYXb3;MyOySJdzHcK(Lv-{LTD4Rt#;R13rgJhm+Q#bTP z@*tR$y{588>PAPyXxFY2G1bS*`A9o@-YSn>cw)S4WQ zL&CXU6CiF865M7%X@qldLct3PJn$guz|tFY&F2$8Q2Dzv0;QutN^mzhIj&dJy$r5@ zvg)4r)2V;Q7zJh@G<2ilqY>>Ndj6Sf4Be9x9_9)43%iK$ZP(CWjZ(qUH-iK5H-6`0 zDZy8#&OFC^>QI+vN1$J3pNl`+wm7QEIXk}nHw4~bX4e!O1 z_W?Xn1lo`CXIk|*;}_=drWzm_BJ`VtuH!Dr>3ERO5DB?Y-L$bQ1{M z$vJkjqv+zQFd5ChKPh{_X35jIr(T4fLtmSf&Bq`mQqo#+8ot4es0 z{A2Jr$1v8Y5Jh?MP+2=3Emmi8oEsAu zyrU~k>hgcj)Gpgr?O)wHUge&EtIWRw{z=%QTa|)w&JXx)UBO@5U^-wuUlDV&`D~K~ z`#XAvQHN|Z&(o<;A1$;ZW08@)nQ#k|PAss!m>H`TyIK7qv=e9X)ms?*r(JLVN3u|=DRPdwW zY36}|s(7ef*~r+cTX2(PR)PxE>~IlZU9tj%6nnFQy&oO{p{DC1*vV%8&ELn_4dJfh z%*K_{IAnps{^j2D0r2femto`ZdoypYgrX+{NX&{Txesxn;Cu6O`njMjlj2Ew=?A=^ za1rd-ifu~g7M%27Tk_e>gf`0`bFbxT&!t1(?d^{YXNL@u0CZh;g_h}8X)+sKnMPY;zhGn@1r{bCnKwpO z@99`eFI_>ebURMiC>5tN4A0;)&IpoZsC^}xP!z>}A;J+r-G{T@b>*jYJA}+x5|~nA zH0HO*8q9~zwZMA;t_3+{_&9CucYa`m5`xCfN8>?_7#n)9-m$`sn!G}h+_bD<2nqa_ zi4JjAq*45yNHWImw+fm1zpjNE>3I(nKpucT#d2=CDZ?!jpgv&S?DQJJu)8&b01D$v zOQIV_IsOcfM+iEY~C@Q7ir zm_hib?iivN>^CpZ zf}?r3@t;DSmb!+$!^{EO56l$wXZ^I<)tZRD+ig7amCu zNc-CpP{qv@Y8J&=m0fI$)`2_)goLHTmoYn`Fr7R0}3G+k=0y*L) zWfd0P#m6?xb_Ob>Bdo#c-|rpSfT?a92&j_VMBzo}%NfyKrE}+WGU@+i?+Wot?aC_LOK_unptKOSmiC!62L|!Z0Sa{ z_Nd#e`xIq0QT($6eI`V$;gOM2u=UEOhWyzwAFyP zT7CN1xL}_wqK-?nAf1IyAMp>|T-A#Pw@$s>aR764kv^^P9`6rqf$YZLTodTJC2 z6oKOr_edlA&_hqa&#C138Z$|EwB^}xf?)_gZ)FpT58?!nHT9JdHi^{s;g@QUif!R8 zP_U({lApm=Mf2Uc1w0BDpP_h_)m46Lnv_Bcz z5Ua4Vs2;^dH$nhc3*AuICLX{cV0r46PeU3@&S-b{4`e8lYkwKgqiz}%Lui=m>&%B! zO<_#CJAn6__L5g90-otad6e5wYUHI#c2pVt8_h=I4VZ37ub&M8_2^3)p%ueWKL18z zV_y*Y3B&6xF^!8~2K#yG6$@7x{*eg?K`B!(+#6dR@}d_ciLdt7mHxpY9dun{jT#QM2*r>hrv~rxnzJ5>#3lHJGZ^J`(G#=O zBfOwNL`Fk6*HvR>M`-6LPB7--^ps*{WZ2VfvPE2H%Pr>`ifjl-{eJKy@SSE8jWxm= zY=#n-sBRLq{*xP%NXk}hm}80^QDg<}3LRC@hOs;VvBSA3(X%cd*!J>>_SyM{$OM{m zee?78Ex^gZu^x)6VUF>-o~>!&t9)Y3?$%z|Z`IXjKt*ES#LQ#{d9GrMfYBoHQLS1+%iV!7)HBLH4G@f z{gD|GNACsY;10{8<{kutEeg36PoK<$#M;qs^b7aisrZA5 zj`N`qibH8W+&R96dRu>2xUkSyb|YO6-MxOHg&Ql8N}8B+)T4cg6*YSUDxmq^N8G&e zDa~{=$bw|_PuU#JO`f6ty`JOH!sUZT*3fR4FoHs5SEy?^y%1lcPnH-H?cS@U#=(Vq zEyfUItkDP3FKGPI_Q4XZs+XPQPW@bIK@_OH&rt*@Vtd(Xu}ou8d)xHr8?|dQ7?$O6 zN`;bbsg1=)pPr&vJ_(STpbF^Hws~uw&ZRDx&1*~`t4`fLy-T)xW>=F%qF|xDJQvW8 zKXTFPSBFjrZp8O2*+6Bg=Oh};hf>A7MT!_b;>Sn;=LIo@hRPlC?T{}fV>{@(Bm>iL z^A&!X!0 zRc}MSQNXtJ0y~|MYctS}eXkA3%Xzgk{*SbrnsN!jh0DTOsol0!QMR&AwUr3_2Ycf1 z8DDdVpJV*AQl{Z>vcwr!7Pg7%{aS6({$jFhT@G1_gum(X(}dqPilB}{Pz_3(p|jgT zu2TYn?Ko=~@^K{!4YO#~nKL70bqN4(_l8DBwAokrwJlVFjOP)zTo^o%`j5{|S;)UG zzyM77Akm&vKs-Y)6!FCx&MC#vkpWcU{Se>G;ZK<|b|WTMp!t`ySAu(XehxAAz3sWS zm9o;h_@r=&TX8Jl-1mK|FXFp6c38tzkPW*ovJN`^TRKZZ^V2u!cBqNUrn^Y;F)KY`HSc+`p{Vl7M@g50 z)4!C~{PCf?4pZCNt#@n#Y-pEdb_P|%cI*xuE*)IWC3EJ_HF4ncg5RJWk1`MQg}sza zU2~?{18tkfhC>C1Z73lq=s(uaF4k>b6?QL=jYF6FTYo#u~a z3#LQlNv_?c3)RWnVhK3%ttss*8JHgIgdM8DdLS}6?GYcj+q~b~jLZ+=<1f-O%WV-$ zFv_^UTLuioZsno6c8TJN_h9I0ETD^J8|bJ-C{>hz zZiE7}DdyIf2+6X5*#k!sP8=CoEp&bF{mROs3DNKckk;VF<&4N8YswJy*&o%GP zf#*(IE|yu+v!f?(aa8yTCl^#081*J?su!{^`kYn8G_H7n)tXV(N1^A(%%e;a7a$L+)1`bgmqC4;3uE#=L<5vK`yZOcP5A)b@tswwA)1DjM%6? z^`Q%v`g#7D!dV&3Ml?1@s!2@eUJD=(pl3ZZ2sSsrf%AUUgpXqL?oXxxA?|O5a71>` z1td!$2CgJu+tH%R&g5BDRQA(cu}@yvA*|T=IMxt^KXi{QQ2~R86OGpPO~>zG0Z{Px z6MwJIwETZhYB-iV_EHUIJn{PDy;E(yT{133am?$ayoaY7(+Ul;AN_Xc{mvfXv{Y=P zWW zvnq$|n=v0DBn)m$FN0l+=&zuM57c9JZQHs4o(MGdTnpLVxdxnyvg85s#!^$+z&oOqc>i_WA@kFG$-qLe>vvX2q1>U~snj=wsiUj+U z53FG#dV*w(Lj;xCZD7HUH%JC(@pVsPyzw__y$egi6OE(lI(BjLEZa6IQ9IcAQQRF_%i78FwK`GM?urt%pyS1)_IoWszf zhp}ksJ=Jg3$Gciq5rFyC0_<=kgy`<`xTFWy*Y>TPHi0jVEy^wDY!d7Roa|ezI6?Q) zURIl7g!V+9Z;uMtp{6s=Nc>D?wlgz9k8&dX!jIuN0c6*Ds0ahzLlau|sdt(Qsqb_g z9&^e-A_(XJU!IT*&)4zr=GnL5sY-euB+N%6@M@5%A?$z{<&BjWGIr@-vVNr!GoBZf3$9|OCY4@=O*HL>h-oHFF5 zDaF5rKx$i}Y$)tDoI}9`@}A^eB=;7^AVLHd)|&BNy61}yYb`!6LI)IgHe6hU;yhpx zBk;XM;AwDvBtJA>ao424P^)Sf9DST z8x%$2gz>mAm&?EfYdUIvFTz8f>gZ@NyA=S13cXXC7T!-oXDe#I)iOj}eD5&yhir6k zyWOqbl4r5vFvgM0;Y_2lI?9yr>Mj*@`ql;i9TOjn1>D4bF`PQGKmG;Zw9&%eORi$h z@LH^d@hCR=coXX}qS`jRHaz5rVALA&N~rKz=O-puW5H^ry_2F;Jq1;`<)p-G?;5K* z^Kg7Rjr)1#Eh`A;1MX(U4W;*#XGAfM;R1DAReAbsLe>HYZBH879 zM-E^f>46+*2QKa%)>mCF&gKoI_^DJ>Yz9uloq2&j!|r)oi6yE=*cn=Dt@!g;+-Qt&sDgmzNzMUk-b8BU9B&;>m~e0JpvzhT&Vo zcR+<2wrf@I@_;SOdAHNpgmg04sam?Y;qVDShz)l5usYRKIVYk>pmN?c!c|?HXu4~8 zf#z#&KyGiN2p%gr(_ghK# zen5nh>&isy0aCey)3E)SbTeG`z$;_fDlzuvkOsWqvOb}K3ZrEJ# z%+ONEF^wYp#qTxl_@sFn2}`Ur%MX9r_L&tUWi_N1<}lsWsgvyX!yZF2i_F%s4zn)5 zbU`s@7i$&HGY#g*HP`!dk5$*IPzIUSiCzJ3PY$XA4a zm*ZV8cgh^^as_Zfu@NwdI2>Om1h?@aoC53Tq_nt(07PT`=CajrIYnzQpv%NI(5HHu&Y`$GW zV$9BWVsw`;kPf@JOv#iiCc_AJ`}FBP#l)hX>5*2g+))=Hb*vMK!$kN+~Y^Y($!CXtP@WD_+inq481~v2#Y- zlMm+4Ca&py*T5??^=cBORqkQqj)5$8eXY>eE?4pkLXhT!gI#(dSnd&y6G zm}qwp;#FZr-x(y2)wu0g5s7_#BgOcBg~xY%!y?b)SfX=(5qty zC3#l-e z`sBJW+|ZxfokUGFA9n-T9aIrjAu#f>D1+qN#X8=ma+|Uo2e9f-<5M0m6p+Eq;H?k;0YrNLeSH% z1d$LdWJHp9j?H*yAi@HosY9z09}s!#kc4H(x-|@g`mP>Ziw;Ep ze(eEes)_MF`OoZ&{3z$iCEt=^4tTcG{GNx5_mPi5cE@wb{ zh^}8-WShIoP>#pfiLUv-qK?n85n1Z~-+VqQ;SBMnZbM%X$qHfK`)YJr=C^@3|8o^L z$S{mX-XR?hx|;u=M(x^$t%P0Pad69VUyMvm=u(*1z>Ph^Lo20{TrSx!N3PF54^UF8 zqZLYR{*QrK?9`RYU_Q>Lomm}Vbw9Ej179^VZD`Vurk*4wTINvPdd}{0Fk1TPn{J z`Wt*QD4a;Lm)dB$qv1~Dv2EVGPDli(lM0Ssj|vI;{=ZhD!WzjqQP%kKB{rq-SvU5- znZdEbezUigaQl=lOpctrb8CX9Vi)W-=|y0PlE%LvEyHAst)|1O3=DwLu0mjkAv{|T zORRfE)D>l+rH z>Y8hde^j*ui5t={svoDp#cUJZk4dur`b7+<8=3>ds!tJF&BN%K@&7F|6n~L&btE5K zks{6un47p$FsdADa%niAl9aVJIjd*Mx|ZzWPOr1FXdq^0fOWUdsM2TH-^YX07~N2@ zq6_J(vLu0R05o_a`vnq)Q9A~4JVfUUHJYW=wQGL)-IV7t7uFrkVKU9tav-YCd1WP( zl>+mb=FLLgVu7ZI;s$2s=S=$%E4183>oIMAtwtB%R^V^-@IY%(Q#xCcKCHxH0iw@N~M!!&ZX z*SAG2?tlaP#E>B=^tTw9{W|5jy5x#$?{;Yx@S~c`y4$dhJEz+C%uL1%1aBeFeLlm?@$g<53m}Tg^Fq_?-L)vbj&$d*!ShDNMgrK3ReL zu`w+fS833WWkv2ew5J(-Bc{jmb(I!HF#MuuhGxB{fhM>B`+!HKS3AG-Br(G-ulCag z9s`bg??p~}6zx^_SNPh^1anz8I&Co-@#tvcsK~U>&Lwr>%>gF2|3hrM;lXLsXkEnB z(Oc6PFn3V`?b&%cEyRpYuOBeeiOxK0kNhJY5JbB`6mNqCRme~sgMT8=?d6V+=d{8N zoN2(b^BsMxKeoW29rYOjxsKDT0O<_98TAtFerL{d>L!5gM`V%_qYA0z8Nhpc>pz~^ zfvwfLO^P*Tcy4nxoZ2;`e3JIY+d|0W`u44m^ajFHOZdvTy-39wXK4!rgqAX=#S-m zG?C!j4*b0TpqWkaY6Sg^UDOwE!O*{fMlt6HjcJMyHRCCPg~L*8T*>nCL_MePbG}su zv!|j0+Km0A6W_D&!~7`D5E^9b$$ya6u-3BoF3EhtzNC}v^PV*j3tkT>M(juG9S8;}yz zg>#ARP{2U}kaJAmmP&9)gBY7K2mk7chuDyzLUaTd@kl;74Z@1WqYCsp4$Hp#5y}DT z5XEyjsa44L>n~?{98o43E_UqJJ34A4CqF#s2JF=>Qtk0D@cOzp*s=iJF@q_e|_{HH%4!E6Wo!R z4uK2CWp9@Dq~#yBWFnnoH$ui*CVBmX0q*+RfdD&oo#j z-zk3ZXD4xbl$}7GX6kbwU9gay63?|~Bh3HVQLAZ?{!9%OV{A~65X5^6vLm!C$@PpD86zoTB~3L1CX$jsS=S)a5J>#fh4vdq*i5R( z`H9fKX$yezmK!UTa?&xq5%a&L7stnx{3}>Nd)F5#=4DjklCl(uoBmVln+Vgabe= zt)w8}-U>mE(VkpLFkd?BS39%!vrPw$+CP74dYD;wXW~7kN71bi3j%6rJIVq9|G769 z#&|-9_M$3vA{Vh=cx+?grDOYExnw|D)11^GMj4%#5}zWt%dl+OtThlEFBy&u;juVD zcjkc+-}dYvu`u_q8!S*KJlq`xW(I>2JiE&pyi}%7+#}86o z`G5bD?UwdS{o6N4ud%&z_+RzkHV>X@A5xcZ^J3-Us_Ro$?RKh}oIm(Cq8Mf# z+fn#W)XSh>X(PwP2kvaB7QEa$f1;YIbduM0b~FZgh@0If-%ykS?-`JzW->^EX2I&i zO>{TwT^HDD*&RF^HeQaJeg4{Z+ow|lhotZu-q(8=Wb}hlEeU4E)`2P7fst^0f~m+a zV0rA5AuAN=a)WydraR!ACKs}J6l$FcT$#fHud_DJ>U_>iB?(&t8wlii-PcAByE5kn z?umSuZhU;%ywWYDB|gvN0`tC1`n24QH~+Oukv#-f6UznFA5~%EN($wl}3|d7vljBgt?|;!MaBp~!7JdW1KupBtD^Uvv-| zbbjd+2NS5^(D>@C|8G(FmX|;n(gQHS_L&uG#x=z09-{{|Tt&kNY}xI`A%mQMkCw)s zS#E2mEM7+d+zE)eDRi#ozMV(+oH!2Zaj=&LnxJk0;5vr|uUSAPjm~!AFR)x2D632S zIv?on=DdvT$^D4jL&y{UFs&dP>X$%9jO%)@LWuq}%Lv-H5VtU&|&3WVhAbNh;xZ*6eZv zD#^J+g~{lYCGFQQUT)}&G(o!24Eqp<(($Nr0C?pAS4J;NXqn3)Bzmm%uudHSu;zr78!Ysk1jn@50{b83axG_FC4 zQgQK>rq>6&iN25_A`_9fd8wmlB*SL7)&yg)IsE`1b z-y z;r>sha+)E-ocrixhpTE}KJ8AT6AC}tuuZt1esDR@e(#<*sfSVt$xdNFYLH%FV+#}JH2c42pU6Lo|TV`*k&S1q9@atSI=@&q1o zUUq@SpTrSuSz^w_k%GKeZFp!QTS+bqmni z&Ou-3lDE)voD{nLfzw{lg~ z`Ar-h&r}R?Dmw_qV$Ri)^k~lFgzhe}Z`dg5WBAHx+~ZeB$QMokdBIBBXcepX4ZuEz z^8fB>A5C(dln>jtA(?}Hh$rr6rT94Em9aF(NFX2ra6so=5nZvCaPrt+(mR)Bc9i_J zu8&q&V@G5K_jh2kq}^Y+TMRezh~#^}=sDovg;iLpu)5g!>XcOR%rdvkhIDkpDyTvx zS%9iF2lRDBOMAQSQm`drbyO&T(D_C-x75h@nw7fBP8OAl@&O=*vB4k1f&88oJ%YQM zgqa$YNmm{F`y+oc>vQX*%;v0JrA^{39~){ym#njNdHf_X5>U;i&*iX})P{SH8->B4nW@>l^J41U5JXt* z@K$Bg6qAt`Ol?(mtuD>jXO2|S0#HbATgEul8{5gS(G})@=U-~tHHMUoG+kn`p z{RVkEDVf1P3FG}xmQxJjw`j_`J$j~n@Vx{d8UZVHZ!Zz|a-3 zuLVtB$I!wQikE|3?h`cdtI&WA- zLhe9FIL!=8c*#dvnrK6BX!6N5xw^j=TZK&7d2)XWH+vUHTyB1~E<1<63`zWB16P_* zvM&@z@#vXC>vx=#x;&^(ky$qH1XT|)6A8vWHxLWT{d34)lY%811`AggDG>r> zje_MdODNxIi6+eYpd$JYVj{t77ML6PAt^MMV01y(Gy{+(EVixTfk9L7%-1_j+_fc! zjowsSf-B*d*a(gU4H=$dv3O)CqNbVh%m!5mMm&gcVg9yf_#CZrz%Yu;-R{#p=c{bq zXCS>)(-be{LBYjOFcbEA?F+euU{J)ZmBxa?cnVMbM*BT6QEl}x)ZW=jINZwSdlRB+ zLhP>NxGn#Ni#LiA*Y9VX)THa>*vU`VOa@0>-Kkr!w|T)GXKzJ5_uOm0qTjqf;#Dw2LOZp@c#ak5V}+G4!<@#Vt@ZG_68 zP3sobg`AS;;D<#m@%baOT{2jdd4hxKxp)UcJ}A)K1n9Z1B`{Oez^&j93lp_ zo2i`ma_B+~JW)MSd#r{7F2dlZl;q-@V#FwKMB#S9d5Qv`Bc^w4Wr2NsmpbDFZs=>lD?%KZBCacQ(R>LX{ zgd%tjC@1Qs=F5It*qh^&L4a26EwgLBxfNE#D~3e&)&Tc4cEQ{$1j#?XXm9-KK1zBl zk`9WJ{@8AT0D6CCz7RWM^w6gXKPbolSMtcqAjLBMZ z?T9Dg>i#HUXcYWB7<1bX;NnnNU7M)P!M0;>IG=5sYc=Q~DkbA-;nNW0_B=*NcmIa# ze=e?l0poHJ<)+jad`sKxj&q=iK&Fzs+^(6}vB%8lXeO`xMHuH4P3k(J+&Yas`zBBz zNALi0Bszg}pb0m&u{#=%6vvlE)`&Tur)82_S31N*M>h=8sNjPCYY!6}wCyMTTwEVr zkk)Htz*5SOc+1gS<_Ty-Oj(~(*@;b+MV&ZDHn))AYRp907ZkF>VklVGsuInu8!2LI zMwBk^HeuM4K3Z&j&duDJBo7@YXG9CsaG^X;21js%5r$Ljy(P|ZhC zj@D$yW`0OcVV>cS?aB{FW!J7GM#RY=%HWzVCpFRo_;x_upYURxN9}q%V*S?MhTh&L z7z^31JCJPGkwB5wh2wsTKCi@m2@VTL^M=|%b&#D_<;)hD-HR_hM_^W1pjL(7G(OV+Br!U_LjC@=Q#tMA}y|}uVi~v1A!oQ?2FzwcKApc-V$vVnhC-fwZ z!qIj@fVS2ow|G3e*r!LjOVRojFKH5#zo%i7b(Qv^)(|$_*h%0jz@<)^ZU0SDX+{d? zO@!X)t2lT3lJNEPhZfnMvUX|Hh?$;49}s}%C7?D{#3_5DX|q+y8)=Kt?)_U8K z8-qr`vbP|tXm>yc0_OHQTXZ@zV0&o6i? zZ8W|@c6?zjb?QN~{5*=}z6PAd1(CR~OFT$A!u!YW`j@hDK*jYcr;-lbzRGO!8@iG| zQC>c(5+&SRVCT>fEXunYJd}?>jEhx7>mYv)8pg@|1LHZ{Qg&AW9DiX@($mkEPn&aP zZ}p2CWrX`T-EclxB|kAy3|m!AcCyC!$1fZL1H=Q&_*E}Lym%nQ!^&K9qTc0kw&wH> zv#9yUMAZ7QLjv+|)3gvDKF8DWY|GMXZuaLiSHyk^HZhgE5Ae$v2o8`lvZ8ZPNW3JY z_e-HyS~3W6s&|9={3m2~i@8*XOph5Xhv3zgSwUZFQjrBz8hCxjF_ zZZ_2qTF9{pU51jKpR2XUKLfJ7XGyfuNcvTs;P_!}sD0=wga)$btFY_Ph#2?gu&n?m zT`a)yvV5^!}dY#*E<={iy>i~k~Ijq z_QJ7i8vttS6IVXvOxB^nZ$~-`mMoG7@$FP>%-hSB!Ud#sh#-d|Vl#QTUxYVFhhG~| z{B!_%GcAXO%KWhI9Cz!7wLS=B+QUyJy%eB}+CwYG0p~=cfWvsP$K~Yui4VuV>&ch$ zXNIf@zM{t=}Bg12~jYhxNs4Z=%mhg_rLmTny>!8sWe})ZP|D z#qed9bSClyn@{%1D(xn{c!!GhaDP}R05)#vw5r7RY!lk6*qoa+Zc9lP&K|8m#}qC@ z)MsIG!_n{B|H2nt(j8=Z$s6ZgVCB`n$GGyk@$M-$9jl^yf%cyGQ|HB@s=86LlB=Z@ zB2h!vWkNl#Fqbea=-KQ!qrcddqcix|>n`@JUf*&QyjqGcG-1rs{694!ama6ZF%=BS zIh<`aiVjkDxgQ+8+~KCMI)tYbsZP+W$*B_SVCEtV8K&;BTq@(-uls-Ffg-D#8coVU zbe|sRvmTT%P4d0n=xjZJ2i$plfR-W(pstRTq5kzVvZG7=)Q6E5mrX+E<7}*$u0V$j zaAg0Vq+J7U0?Xp;+PR|~3KwN<*whKdlGSpKY|V-f z=;Z?@)~tjfH^|c2q?Fs~0!^h=I4XQk|B4wc(h>q22Lb4*(r$!Tr#}V6<1x7bPS3Zo zB_D^Dh5%?DyOJqf+YY=MVTw>^+EwGartDtM_ zVe8ph$&Rtwxyh28AZF`p2Y#D;ccQ$e=hB8a|8OD2M8DaRY053`*%;RP4(Z9r4^l@! z84T$qO2An>_Ub9EAkt;S*7W_RR4$_0Nv8k;sWDW95({OI{v*CKTwcycs{-D~^2FW} zZ7^cku}#q>%bshRSXWf`RLpj484J&Uj;>w^Wq6nmUJs*iRG@PFoItlz60g56_OIAv zmiw-X++U%)WUHPjv#1QB_I|%#36l3Y{Ki$^HlgK$0#1_w)b!${tKp$Rhgh%P`qML3^TC5Um%JC?K26Z^f7BxD&}_>E?3Bhs&rEH{c5G)5?4av&b*m zYn>7%Pf_g5Dw3G!Ys3!`yvcdUcXf%}R?zPWJxd9022azjl(i|*dULW;af^V}?hd*5!5u7z{xBEG9Ain7?e{XyBuTCI>i6HX%I~$m)x2NX4X^#v->6G5 zP9BS%^#v}bx2Om8xJmm#bOZ*IF>KOd0~5O9yJr+y8~Pal?{?0*ejPL4?Q_u;W^0}Z zh(s>0xgBKxU1&<#76TgxJQyW%Hs|m@n>(fvG;EmP-Jfi|()p-%pju2{VW-q*#5e*2q*ed-P=VSIo`@}9c_%7rdzsH(9pS4mO(c>Sei_*_i7a`<8SnH+ zokb}%tCFFF7+&Wm zhx7!4Z^cBx+=(xnL%$k7BxKc=0=8LqrKy-QYl?J?na*ALq8A1J!MP7Ix5zBP?Qe@< z{grPn^7vm$>M>}f=(}cI4sv*1AqvC$x(ya#8G8btlplvFZb8-w6_9lI`DoKA$EX_a*k9U)bbssfvBA{NWJh!>I3>eK@7(`FZb0oDJcW+%? z)Rl1Hq(Gl~?k?QE)=TuMs*F|Iqg3+&-&REgoWdmW$pDi5BJS;jlS68u-j@UQFvmmj zV1%;-vOjJ}#*<@ff2xWrj*YsyXT~qg1lv2WyvYk#pg@4#W0nbpZIxrk1_VMoYS-Rk zHBh=zUy4c5A7{X9vHJmt?U1UouC=G|AjmfH*yF3nuDok@+K+c9n%(w6Rps*?9_ePlzdQ&RW;4$1m? zZ-^FJLeO_fKBARF;(NPs6L)`+Y%MYmD=nvQEMVl0(0#sFrd`i#zz-G)@cBXh?vFq_ z(c{U04XH(`t{$nssJRemaYA4xOiYsC5So zazcjb=g_cj@Av<=D7xR z!VKtd&wojazK}_i`$`^M{8TW_q1pUf8#5uChvn@6ZkNBH@R!{0B?)r=O|-?o#3QhX zKRMTDY)s|nI7qcz9W573<4c4!o;Th5cGW>59IgwYB2`sQ;I)^9f}QbgDCtc=P&cfF zfIZCJm0s)D&NRG_#6w!n+FG?AJSijv#f_zssy1$9G8b4WNS{*=OS_vxu|D|aEoK%s z)6TAtSDM+h@lhorNA_oB?N73J%) zK_0(j1cw*m3Y@7Et%vY#K<1bMq={W&o$L28V8He7240iX1Ib@0ci~iP4Ve6b#GVH? z6lmH((orF2f4OfZFi<+Akg?MS{_Z4*2)%fY9z8(7nDC93rT!xq?`i$JO_>kBiJ55MlJQfN-8kQ-mZbuF-Br9$`Av}q$! zyZzka^p_`{e>*Ee`WGeHwJhhv^ps07;Myw-Zb{%HG>ClQ8-SRKRv0A6EhJUd{VsO% z@teSd)!IBO!5k8jaG(4TFhPw|u7Y`Kmsp@flM0uK>1~lV9!7~~tH93-P zE;@2a=7Ux+62~?a9)y?}a}w^7?n-Mk&dsK&MCet(&*Ng)PFXvIQ~xk43iH$Y>L_l_ zGZ+e+`t)(O#i4yLx;`Ro08u7k#Hw|%g@=AJwkB}t8Y!Ne>P?g9E!F*bQob&<2#P*q zgczLl9#tP*tbz?aLyj=VfnG<{gM+gPD`eGCYT<5uG#Qlb#EFa8!m$K|@wrvqpLqm% zBMZOmd}EK`lIpACT|QC-`@Flt!em?SfQP0BwQ=a^>g5q-?{D*>6ZKX1$arXo8P4 z#KGVfye5m+)dc%*3bJY>j{;rSEFK)u98F8~^xB2Q2pbO=%bC=&F|%_k#CE)AO+@sS zLW7M=y)>M?@DCTcv)9WH@vbFyO{p+jTO0 zc=J2sCalWYb;vs(X-vGDQBrzZz|8lD^vSB$Dxy^SFs0In`Xm_(z|yxVu?vj zCYQ@T3>P7}4}8&kSZfTpIW99WPcgYGg>z*G<*BzHh3*Z(qXOFj)|%Z9k`hOOK?5`x z*y7VjeagpU3ha1E>B*-6Ppsr0-$ig0sCe5`Y8 zh)JJ`vFo!)q^_%%1MRs{RU(Z8qaB;QYZfEg*z#0@goJg2EcUR8+94u6Qq2F0i!9~7 z63HXbzjqS*YopQj@KOwa7@$t3W(?|dJGNIx6jTgm7ot17W11sq45>>!K`{9x0{KRR zZgL#5S=p|7So7TeKIx+Jn?P{3^;7<3bbeiw0(p3dmpmxTI4d$6-w>5m-8zW^hLQHH z;nI(_-l&@O$y8n^6$R)mt?YTAbTdTyHk$!Bd5$C$Tz(yw3Z>!yVuve0PFec_7xome zCCKS$c>J`j;|>e#A&b-~thV2jUcitLAzK(I9l!T*iJaKv<_EQjZG?EiA-y{n0;VYi zZXzgxwLmmar2t0!Fv#mT@4ds@KX9*Lq0ULVqdUo)`!1i1Iaz8F=kc3*5DBJ=Q4|g_ z*41>t6ZvSq7XviCx+hankogBEd|}bEFkij9?Qa_bTwWF(4lA7$=+GvJ2zuDkU294Q zXB8!YET|N%c9^?#h0;H9dN*y)IKQ8l6(@11(1wl~C!nTFJOJk@tU}K(z<$qZP8#^H z;!^d{$qd1cGp_bR(FMgBeW3$zk%BaM5pUd1?{-OL_m?1Fl<3zVxX%oGUP9cV75R)3 zoo{+P9pH#Q@)e~f6$i9%@HCg&a8vrgS!K4tskDiit|{m}0?19&{J2J{)AcuN{N_2t zpwN1|SK~r;SEjB+h+Ko07ZCx!Z}wtT@wIofN$E5f7uZ>V5c*3oqK(+l49vf^ZD_=w zfqqp}?1kY2RR#IsW^;0#L$Q9%x6*3*_-Pq=ydOL#yMLEnF*(wiYZ6z9@f)}>OJkIHCa`iy!*7ggV6I0ml5DRAj%hBhz8Czl_Eufo#OuX^3$UMwN2%1^nmn zNbVMjKFX^&Fj)S_Yo-nVa0vKsoaC*B`IClAa82>%KxJkd$P@i(0fu1w z>Hcp|1e%h5pjP)+FCv9!{T8FFLNoGs2$W50{! zJwDdU%hJT>W3V>%m5vckTY>ZeP@~S2tQSC=ny^29VdkY$eUYm#L5p|F*LgT&&Wj}z zj=*By=oV>CIv#K6)|V*s4cO1y`1hq#s_yG2MGRYu9$@;@uG}rn5+8q!cV)h1iWEiM z4iA(oTwY8A8_-hG+zgSRR__+4ya6^SE60y} z2|5B)Sm{{-u@2=`4dC!xzduQw_`=QsCYIY5L1_hbKId*5miZlE<-WZcFV05?Sl>*+ z4oJR-FK3G|B@*{Da<Dd&-_lWnJJn7eHfRugWH!s6P3kaNhy zWF@IrBjR!p6-6j}O%iQ4C`xs#mUJM2(#os2&kOfnr1*MIdeNbvLWtZ4^BlGm4!~fI zV80ecqTVJw9yUXw8wwqQzS3s?Iw>e!dx@8pcqvdSshP)w!VGB~n)y56tvlqB=iv_y zaX9A&IH03Y8xqpr0;2097t$8VCfo0Gg|DxTE7WGxx>YfT+Kad~Jc?>q3V1bk1mXN? zc0Gf;u?VYY1BowYU=OfH+ZY7jZ%%zaNP$XZBMzfr#&dkk(kjtqXz&op9U0@o1IPqk zu?RtHRC;x7B46rK5wUfY&}E5?m?TPeEM+=CK8nF_p~i{C@SVx0PcJ8n%SL@Cl7)|< zfP=P67Nxc=LsZ*Dk#-FWlXqOpI2xs3{bV!=1XnTax{QVk@&7%MnQ2=R#uO?5gXwe+ zK9rY;h+|BNi3+ydsbf5S#s;%_>PkP9f_II=pU0G!t|`)^HYW9!i8*{ux4Z(ZEuT&;1c_&b$R#2+)#`t~O1nBs;|rCjX#J$JO-JX;yu+Ah zKL-MayvZ(zy`xRT11nw=_51gPB@fhlV&cvD1?a>DV5rp5RXv@(-F)CG)+s5>4ZEf*2vMJS*;B>Og5^dXChUZOr!|1Jm+#HyU-l&)+Rf^kwC^ItsFD9T~`;j0Y^H}vP+)HZYj`bE(WeA z+1&{3_rf8uXh_Fge~k!dPJm!k%OM5>b(~Up{4X6KEOWGY7TU--h*ZrMsg*r+CjVZ2 zt9&T+6^zdV3-J`m;kLJlj^M+^e^6b4! zQR=9#KCy3R3Z5Y}00U@K^<%aKW{+h}8`?la&rEe^%f1;E7tV=8ps||610?$=T1T;% zR#Mc99i!1yj%Q<#W|1~on+(Y!&~Fs^+JYpG%+{+Km5j1!o!C`ja0Pcz@!XvG@DG&} zTRN8|X?05OJSN4aKJ<)CFFt_cr}_GNult0F*LB9`Ced>x0TwLXo;xu+;WP{d+0L-T zaxa{Ab;P>T*7CydYVo(#L0Y$$XIq$RN=N#;@s2Dm@R!M4eg%SaG+ae-DOG4&QCAak zQ3k4>P4*mA&1@L(W<+*gXR^Bu1ET8})k3{3pYk6YWI+-#)V=8%$y;e|8?;Z%i6>qv z^Ql|(1k^pYq=SRrDvD%~xRkF3ufZ>;usn;H&7wZ)Ox9;OfZ+ou2-s)0a~~aT`T`cg zsYOp0_MR{S2~jH9@y5S%i3GT0nxHkDY%rG?H63loVzz!h!Rcz)Fo!ll8gv88n>Skb z&@c=SjGFvn%@j1=pV?ic-a!R}==#2o3^jCa)u%cCM7XZYM&ENkFBkGF_V|ZhY%=IMVjGK_sT;8=Zp|elcBYf35$Hb|%18+#-a99a>i>7S#Ct@Q7a*z7w$-oYevT z@99|{yp#_15v2kZZbH?FSQr$?akK|*LBI< zUT84os5&)$A@OXU;ot(kO62XO+Ol%$$v0wA938?X;JL#Y6PjQH`;@gTH!HOdb`Ime zk_*>G1t@$5n9$VcC413hfB>(W%(4c4Y9;JonZ^KlGF4g??~SJMO&WL!#jC&>N?XOn zjaQIxj(Dh6Kh#L^o@(2!B|;9}@u^(ZIfyrx+TZ#Wsyj=|E@=XOZje9BVH1(V(SDJe zl|ziI(X8Wj6$lpKUyUHt6BxT%;kucEql2XAy7SXkm=% z3wWpj5_&}5C#|!2pf{K65v)8CaGp_QssIHe1TzUuUWW)_>mDcl(vR8p1R?emlMbe$S~i7TL^0qnN!!hmceHSFKF@ z=G{g8N%`088?HF<;f$SN2F;X4Y?U# zi6;?&?`I?82gA|4OV^8FbD5lh8(ly8F2Q;JavMsx_&d^ATXs<~U~cEw8M>~0)H;*) z(xr&6kkEz8EZ+OsXY4jC#6++E_YEaVtDzSLs37)5l0zxSf@=}7xq%o`ss(#W+60TE z`YR3Ru)wTjn5jN4Z>TqTv08XkRVW28N97PT=5u`Nz9%P&)-S$~W)FU|5t7b3nr%mm zNtLECghmhC2p})j-*)m6v7{KbRJVq5l3EB1=?AyhJ%`<+Aq{ift>@;WpNK<&ya3F> z!Y`DmOP6cFnF`a>7Rx!@Vndi3#Z>XJogXB`osG$m1~g2#)Lh0nz&cH*BslOno~DNv zSm8fpz!t-bJW@oRyOU49QMxY+m4f|4%+bML9S(ZPqS$3ZTSMSDe^zrIJmQudu<>m) z2mjBaSr>M8$%v6uMB_Q#CgEIdi?Wh~2^FMB@o`EIu-KXGeVtKr@$pUR3EOTtnW>!6 z%E(Unp{4KLo7+~<1g{Ux5Rx9)UA--xvEP{H_$y82m;4Oa5nt@_(xkZ@gA^t=1d%jJ zUn@0_W;*1E^!awQU~TXEPqw~YyGh?|rrJ+vs1%*`Oh$)8wjiKaN}()c++|kIsPDsmO4%>L+en6Hk73_t zb%Nd!0XHd}_!@Xos}Qaa4Xiv>2@0qtV~koU-}2{vs967Y;LYF`u2SMBOL6eSxJL(9 zGJK}I(7d%i-I(2QC&>#S@OE!#@AP;JaKafMiZCcS&UPJFmxMv}p04MJ)?NqTns&mp z;r=2x`MflLj!yFa%`~vpBGk3KHa57ptE-F#<~YM%3t{jJK1>-ta!1KwN8hcT;W%l? z(}GYUgQ^d##Rz$Uc<7bl zh86PAiYzHd+DYN*K>R;kGL7c5u~Yx)TiII2#rBu5X#M=Mryq%l_`Pp*RDFEHt6pk_ z8T{0Z;O)$%v6;BPrh)YhN_P^sjpvQDb4$J!28 zKPo?G6}<*HSupQXL1SqYMRm!}N1Sfpu|hP9mx@PsD4~{+#KZs82a`&HQj_`A;tKmB znqmh+L-2f%zOj5auWzvkPm?@RZ@pQ%;uXV<5S*!6ZP*8iO4EFul%k^@YNsdhUTbY5 zf9mg*JwHpEr%_e{St>GE^fOTjf}fB+UkA>>zOw*KlZZIM`|dhI?AujV9o+(A91r-A zU^lFn$#`-r0Oz#U$A@A{MqwcMT#PD^K)J>*WU8EEhpzUB>esoqsA&SiglkNZnlnTVuLFb<4{Tt#ySzzhkFq1z(| zu;}PejOPN$Nfh;FnyqUXD#*iS@QYTW;6T`B&8i7{&wCV<7HgYJ99 zFlrhM3}hqYjLv?NA54uqn6nrlKct%|`z**c{F=r7+A8WMVHFca!*LyQK7$Lwcf=6| zAMm3QQZY;EJw=?pWp{v?hcm;xL@xtqtDR^rI&wBNd-(XMDr0XF`*pZn{pYpp$&Va* zXbP_&-8b(va~_F{Dd$FF*l~eE+*X((-{jJrU~>jEVWNzx&WP%KF7Zg0*h+Gw5tKf@ zA((sddnMo0m*1~@{hZNHAB;s@xs{uhyTBs#7$(7@DpUox7VNN=@tkJcRxlH&0wEw+ z9}gE0j7z^OAZYm{h)WjMd04JJJ~hE@^sjpO9hZrT{>ZaDO)dQLsk#JT&B*)106kdB zY}2{uE0|huv36Uy-`+f2DPdU=utdfeKte<$9Jc2<mBGs zDU|9nzAAE8I?fb654m4SLm1r5#MAebIx*=Zz$>2g)ES`qJ@BJhrfaIG9t&|c9pPx2 zFGxXfKOBXo5o4)=Tu?XkJ0#K;*wQo1jAQKbfkgUdZAK`BY&e0xkJ>M}CAOb1mD@~u zY`@wTrr7?1_7aDUBpFmPj9*%*a)?`tge!Na#H-6yZlcX`ty0ro<2|;a6~W6gyUs2R zdt&`J@>ibEztfu|VI#LuV`oEVRYF=IN)2Vm2Da{w-)Yasw=5L4MwUWD>QNuwdOB_0 zBP5^~EQZx!1O@r|Z+~~UPpJ|O0mIx14Gsujl@bTeJT(oEAB7=3h7B;8f0nI$c@b6= zxsve}!wFG>&fI1y3}JHVfc~Nac@L@Oi7G<*PDhiS0psll_MeB3wtd@6hffo zgNzu}wFdPv(Cy__^0Wk~0yu8qYqDB}MX% zV2X461WrP~MX4A)o=XCQ^wX@6&~Wku$^nXf3I9Qq4a|n85M>h4Weg)tJb>H*OEY8r zlO`tK6@O_QPHshLpB!Tb^8ad_srid|1v!kiSeDu}4>U~zDmKawG>?VfzQLTiK-lEo zHBsEoas>y6pM8?<7OTb=q?aeU1?62aY7Qq>YQWdsT5uija&gIvL5~5Uc|%CZJgKNV zgcf;;!tKrnI>W)S&X@hke>Ww%IduVf+7Wbvw@flhMbNPvhn%8@qRrLh{mdROOe36z zV66F#@*005ZPml#?1BOnfctb3pO-=zK&Mqvf{@MwW(=TVofg=J?ll!Ba-TF9)1rOPbpaDU910xzS(!6F=$>o&vhD^7ldG~z7cS%=lK->PtBwE^<02z1)0 zu=##KZZRz=QRv!E&Y&u@h`u{+D;jPAP65yKmLzWPxaO24BlEO`QQZ}Hqb0$&Uf8Q6 zd14fW-x40tEo-UR#y8|&JC9vtwoxKzeQ5#Ys0HANRSZQB45F)!=56W--%^b+Z* z=xK_(S{WyfIZ9^8mbPN>i|qBq{J!Vn=MqH$xVCFlH3 zl9?+tTy_rd7*(7NB-)$7 z{-gazd@25g-@Ykg0daJOz^GpT&HQB)jSjyl7q15%%IF(ibihoc{9WvP zBaaz#R<0%i(8shMNh=N^He(h$&qf-ba{;h@2?!Ybp zh4etfqFaSUwW0*%sr6N9;Dr`rcFreNfXc^z^RALR044b79gno3K_Tr?ko~kvS z(quiRv4bgmg}e|p@$u-eCWdDfqCnvGYiAzf+50TnRYYG$7sOT`4QJ=87VJ@vQz6s= z`Y=Y9nJUI|{x8s)F26CxPHaq8BG=#4i5I?_9Z0K0dDR!zYo(ggK5v}WxUF=4);FQB z&q|W}4ocyGhvOR$6%uMpB!+A7y2)ROaR;(xMHpDrld)aO?rGo7pKR%63x(Qe@pJXCoToi$LEoCi$@clyGj; zvYtmT$iJ&5mlgNKA`KyW_lq3fMRjD$I*ng2`jja+@1TKBiXr z$zkPm-X|D?5KwZ$aNUYj0SyO!5VMz8nJ~#%cj?0I(awG3=Rcj>ebn$|fGIkImAt@9eV#e_pGyL3SaM%9Em%Sc_Nvbpo8A-n?}$jlLE~ z0^>zM)|;ledLMdk<~P4uv}1z)Y7}lO2x3-BNp@@6v*g>1Ksv?P%2_>2cg=N=|2 z;fOWv-q7UrF=eSEW;qTQEWNMgtY~n*tW*>(n&nLlRVMa;EAq5x?#3b}=#WN`0-v5R zB-8sx0uJ1cS0hK+Q7-eHWm=ifUD`Zaxc_rpc;7`*RJR{=Vc8wQMC|6y^?_NDMLoY6 z{_K2)=~Jmc&zR^2iEM2rQK%l>`0XxbH~DlJW5ck(>WI`X&B?L-j2V?ktg?_>mVhjH z?`>V{@LjqSg8E3Rk}8%MracA5T=5|pY!^nV&w*3%M?p_bA;c3ww*g0= zq37#H)z<-`nk)j^1Dw<>LD2AxymN;IPT1xx8eOML{6PNJr6ZaUh!||rbWY84B{7#n z=QfmX;R!fbl?Hv0v=}iY&mk~}36bqeev{_G&gREByo8?Nu6B4^;yuOJgk+P#&!d48 z@TnOAt>oy*ZV9iHc8FUU#>9zs5<7_5Jf|=$vHh5^jx} zZDaQVu=pZAx?9*+M{AAsHt%*2PGa2n)j8LlrnG}Fm2xuz!Q)uD6t(`WpIZxdTETr5 zB7^1&YAk1VIE95j_WXsGGr&ZGf)x7T>+6JRid>}s*Zp1TQ2-@D9Uj;DyvpzBGv7G- zC@bJxa#;2<!`mFi| z7sj`N2^e9e^CUNAW$+UV&RcS(VJ~L|=Cuw5E}6r%*r1OnvK>kIb*&dC5-XpAjxR=kcWW~}cJ zu8jzZPzKk=CULE>H2Lmf;h8!pX(@#LmpeS8BnRs#gkq8CSf2PcfqrSH7m+%~p>;oUFJb@?-et$%MvibH@!?Yt%RT z%K!oU@k!c172QY_Rh7tbHQb08j`e#@C4;(AmVvqk+)kDRc-7YvO109sK$b|K3KZ?^ znh!LCUn@umjDy~c@_pk2X1}@jW?Uwp@#oX-KdaTKuEVU~KRkPnF)VZAGUp3hR07GV z@Kb)=Bf`X#KcQoO9ITlXdiaq(d{je;2!07%a-TYkc2x)s0KJYa*;y!=t!mCwceyNO zVTAI9Vz*Rr_oSgP!Oy3mNHi~H%b350xd{(_;D*TphOj9Pnz@e~{osK>&h^AO^?st& zpJabA;im*lziD_g;|bv z#23y*L%a2qSu`051O9|SJ}npu%4-=@3KZ}1*E9TYp!p~F4XQ^6C4Bn`8(?RW!+YLN zxtE;^9SpvnKGBgmpR6*pYUZQcYVDioJB)3FN}^Kn(XY(}WChP^m#W zBZg64MUHKh(4w8O!dlU>IigvSFndcR|L~|RoFEEbBm9BWaWBsm1qIO>Ez~51pcceR zsv;uegK5{Q7AbUdt&g*HU^42l6j%^iuCksU!gbAxe2nielt{^38y7;i$h@zACv(Sc z5K~I$nHv_29z`Vq%O60d?v6da+rKy}%FkI=4%94+9u55#2jTEN)zQmZW9t&zm=F#T zeCULRaim;r^WXl-5yPDOQ&&*OZZ z5LMRT-eO5n>5?aq`qQ8uNs(Bn4{~OcUn-$fNBV=HqobOelGYsNzAL8s2qDkxe3Qit z-sKmR8OF6`eJywyErSlesLc7{{XHt}lbcTM$_U@D@Lt*N_ruEdt{i%-m<_p>haD3A_~XqSW~f)uCK~MJp>2Kp`eXPKXFCJcvm`8MOJX23Z~5kBRIS+nOYq+tUciAN=( zdrtE7Rg`;1V4c)Dmz+0}MKT&942kMZ^o`>%ngx^mBoUiiT>F&i~M@6qad?q z^-OsEQmqqZWbwRP?y2mQY=kdxa~y=9Jfbo5T0F2qGfUDrwZV%q2R8hi@OQgMaZ8n8 zgXaR@#tydi+`Je-5$~a%FrSigWDDkJXy&--b}=+*`u2vJzCE2GY0`;?%12ohS3fNO zP2!SiA>AlV`Hjx9c*sc|*d<((p!`&D@fbdi;*2gvX{7L?7%3=*IN*@z4sA$6adrnl z>oj;*u?4zwzJAMbS^{eNQ?o;^IRuO;J|pp-i{_s=kKbY}nS_cC)DE)`sBu5V;wq9( zt|9EK)fSXkUQVHZQT&Q&610(#ye`lf2r~c7HMyDbXi+VHnuB?fEC#(eoC?U|B~mGc zxI%;Zz2umfjQ^iC0axe{NF zois6ul3zh;gF1MUopbo<4kn&4^+!EQsinZ{C4HQE>Z}R<`xQoN%SSW<&a+|Q?-@ms zei3zeD{7mgVbv^uapY3y>F*XatQXqIr=I#pEMpZ!*M0RG4KLDejk*VDyMy9ToukJ+ zxmp9^@OR|8#PT^;Dg+!Iax`d;s7y;Cv~O5k+57*221py*B?S_I&jB=x8cin$Rq6eF z)_8Q7Me5@bsZe?ZnhhGxx-rtw@l6GX}>#5PIXfw+@7IG+t@knR`az=p8BV1DSrZ2K{QXul0b5 z4fxF@9~XPYhQYCNJO8}E=El5zR7Ef9ngRGS&Cmw{&~3duRMU3D=9!t_(`{>6k>1e_I-i)ya| zxp~w~6f*dBUmm9fpO_4wq`p81s_lBu(lVyTyuyw%EIo1=Z40Pqo`7{nVn&fiGC#Pi zgh!FFFPo$O0-EMdKofy0&Y0$VniYgI*xBBvtklgPt2vS%1$g=pQ(F=*r@1k}byLEq_APEY#u}I5VZd!sKT^39Q?e5DwT4bij>brPBKA7lAxGiz$$T zWB8tCI{u3q3yFP9r_;|JBk?{&B0f;;f-0ZFDi!`tcUWq6J>A zZ$G$7!#-B~kFjyt7ncX9imh<~aCzf8W$pFUmVzoM`w2xnjIvikvC8o83PI9!_1Z0? zQvF*%(fLidVqo@=9Tok`ZnRp&77@kwW+55dvl&3&KuzCI9Db#At%S0sGBC`y-@5u2 zWdl+a-qU2%zh0zS3I;zZ@mU&mr)Ei7`P-X)_<->UhYA@I@jsfs*$OcKxgxHx1acD{Xj zukB{c-l$yXF)gaKs@l^tZOz`>5{Mk7#S4CF;E5fGrb;<5L7i1whM$CVr$W@R=D$~ zaBf|kJj@=JU{mL6PwI8k;UaZJ;lvZY%;|2H48nv8FcvN9lq$XpgaLP=%}^mC<7|x< zMakUX1*NF7Y{dwyS+b_+VNts5cI1d-=@r(@l zFm=q~0dw_O%>wsknNbbrb>E++AMyEz7p%ifN0t6T)VGSRn{bIHC!c>PPtTJ-AdrEi;@`G8TWPOEO8B*4DIpp&b%{1i});iN0NS_|3r9c@*5z3O0^`$pN zW>a9W&HoojK{f4ZRz!q`2sh=KT^&g|eInE<%OU?ENgm!XrRAkS#}FTg^_!h#&e=zY zWdw1#^_#h&lVp~kB46DYhyDg)3-kUtD?q%;fnMtRs`qAgl9KRuEJX>(eh-SmxECI` zyI?-UYSlF)?pDvufk!ubIS>OuACDpY=%{ig%R-?2=LAT(Zu>tR%o-VusCNBbK^n5tlMqPBV zlQ*-A{p*sS0S(dcAh(jI#H$ce0 z^@^Jiu}xAwA@uYLo*iFA^rv7lakoO*U#xD%` z?tY&Vq5NELJqE6iSSB9>Y`-A1{)n2`E8Gu}>@1-5a@Xl4bEmyVE{@r^LgBcoM|r(7 zz+U!s6+R|@Zv~)JqzYvdR>j*^PvqtPuY{ObX_~Lk?%uua8qts%wxzI-E&h&Q8}lDg zBGbL0BPPd(1MDPo;;~?3f0X%1wz<7gO6^MHMZS~!{>iZc4JLVcmL%VU#jwWtq6^V6 zJ;MXAi2~u0l^kF+3*Mqz^mGbF-A6SMdIhea4cO{MB+;v~ehzXxnE zQ}k0})zBRQ4*i}38c*?ky7TP!9@0ySv3qXGu*fkQ%Y!s87lX@(6vT#Rg8+)+Unn7T+TC0%DQr1ciHn zt+vEw&ZAcC8+HdN$9vm}{@yUI!qSPgQ~w4xH$U$Mp7yaTQ#yP1|h;Q8bn<+BU z5nnSYWCa=W0E|Iijh9hZb9!_3LoONt*%`^+W1Y~iT3N0jhq3>xod{!eek?Tm?qoMe zF0CuPPYouF=dA&;ewYhBOcAeEvBmohX;+kke*Qqpu$_jecVe+$ZJnaC5qo24@a|!D zaYDeV>&nt;XxVW|li)s0piV(^sJM0w`DOcVR%M!+-j5~H6`?q@Z*6p*N%US4Rfw=k z2W~ruP{8#Zks9C57-QazdUDLm^xdurTrTyQFabRDx`m<6hC)(ihJkrEq@PBrw!)?C zi!WfB{wdhl3a|hn4;oeDTI!mE3ji$nm(7qe_fx8EZ~v^odb1PRs0i)!(-<^Ao`ZEX z-PDg~aUS4)vTCoPH0d<;R6?K*_##I9o~iqDlTu z_v7{as0bpRNDL&=3HW?Arq6IbiqHZUt*G@CQm(S$nTqsM&7w40r^~>TnBE?L&M_%e zb#^p(uJf!G^1jAi$c9o~Ty>2b_4&Rld_3r%B1Zuco{mwN`Sy~+9y=vw!4+DW#tGYe zf|5LvhIISQ$&&l^4X zWz6dgD4B~G)G(Uv$IDg6L}@zPr4<$0u-YGF^jlXD`gHQB63zwM;PadP{{AxK%rHIY!y}n09oxC2mNt7$r2m`M z%|_(J#F5K7XZ|hy((_tkKGLZxyQC=mWI(0awQf4|hPYEbxY0-a9{rsSS!m|ADz3Di zvQt2HakU0SOSyN%BHf*=g!bF|oAt4{F3V>|(1jjGsWtJ8c&VeMYPr{jbc4@(H1A&o zWQO;g19vl>;%nI#@T0$?9o08hoCN?J0J;n(pc6@YfDzCT%97(nNC0udJA{k?I;BW5 z)j;MGP_PV2HEoF)bCwj4w8e89k54^YUe z#7lYd>qDY%o_(-%iS>eKO~246p{|w3Y09Cpgh0yb7j3iXgYZWg@_?K43K{{9D0#C& zK|==n?M(A~@R+H4)x<%7>KvHSr&^=%impgrOXJFxE&^Tr=X(Sgkw<8#h1ijQWM zTEa%3q)(iWLFtP5d81^!4^3n}^jXz<==Bas3SP6v8?{l8rLs{V0SqXs@%>4TKl+i- zOwNl>$hxwvuEiN+5W9LE>N`hRePnIgC&}|s%0J_jyEC5(i7Ui?QN?sz)nP`e`mWUo zG2~zt9WM|-FqkScfo%sGYFQL(5l^>1oItBs!WBzr^pB@ICr@1@C!pjw@)o<`x_LUt zgGFVKgQWqFa2%u@^X=rfM8Jmr%iS|+c|22x&1WyO=Aoz9vGONTmfs*3Jmy=1mu&Zf zspzb(PMNh#ovE;uh|de^x7p9M%fTQ96!80L!OT-VmuTAMkUy6SnV+Y*XQ?89{zL&0Kc4lUqIJ8ih6jSt|GCz3nhR*u>6&zmmjlZ~0j zP;Xyr0;R#dOU@zu_6Lssbcu`N+jG0!?{o0^-}d};%ZU8@Xtz+9m1b1CKN?%pZqN-F zF8mW#<2kP%pc5F%FBPH7OnbwjU@ECITW(ZFMo7g`=wI8z434aUBgCb^+78XMxHH_8 zEu1|E4IZN{=6mMFLB>H+xI9o@q{U=5V=COeZh|OJV$jrHz3-}b8k_;h=6L3Ld;&N3e{s?)l zX|=H+jBRNYlAe}|U6JERM+UGri@Iml?dxikx9fC_nGy;n?T5|;v8^}?^mn&Cjc+#7 z8HRyZ>}~5=z_JBta+MjXj1IAs(co*$#C}5(g$Ph*@nZYJTwgo3%F?@xjiBA)Pw0NL z7-#r5!v)(~!>qx|gDK;8V8h9uHgCJTTsoV633X;fnH*Cr6-29y3ctR6piNRDI4J=! zFN!-Nw#y81S^pDFSg3cDfQPF0G_>|AJGs2)q)sL>f)4(C2qyaeTE&27v=#=qR|ds= zeB;|0WhBmHN^6=F?`BQd@b}oUt1E>X4gjs7wJK`LoQ&F^7+t7;!Ft3(@2StUUr978 z`rRv&^S}DSUnA^Luvkh*kZIf5a&|Z&AE;=l_L3j+ZX$44tBh7y+jG$R9>*px=L!Q^ zZeT^g5B@y(Oo#Uei+Zx@qbD=!`pWQ*C;#r}jCDEeXBJO|l#edcRL?7(Vr=P-wPJKL zSORw#CnAatc=aN-EE@YxR2w9`gb)oBFx(pA53JKKuM^Di49R_fhSaK-{%;2uJ#K>? zh$_>onvL;l&c{SY>BnypxXbzN1g!eYdIiL5CF>Pm_*wYm)4nLykR#ip3@7b%hZ}eh z(-a_gcR_FTx$((;2*TqAPHk`X>WccE1wsN=wcvE|rr?9VboDE5lmzk3vNMnkj4%00 z2**aAM<`C1M4lX;VV@fk*ChyLV0oZW?JChg?$ul(K)9g#bpL;p637XBW!`umAJehH zjGf^qunc8~&;0X_WW#2&s_Kijn?7HPGb7g;Dl00S-Om5~2DB4@N@$WHGM5E$6 z{1bCpE$(X4lhz-PKrF;vp5Gw@EP@I3+PiCn1QtH*3iQA9<(~-UUrcLmxUQN?QM7&H zcPf1X>nO)%ozKMw?Mo$odMuwSC#*r6oG({qymIB~YMsKpPtREl1JxA-&uQ=H6q!6y z?@YGam_f$ku4AfLAP`HBO2v8_7qjsTt^&~6rC;>QSdxlpngR;{WDN}2VEf)X#}7$ z$mNbZGFz7A431_s%Jn-~uENgYavI;Wm>Dhq#-equU>_zhJ9OB75l$RqQ&DktvY?;H znnzXjx8wN*D_xoFg`Wes%j$OWWcK(l!!PDVTx)B|UVAu(OS6pUTsJX(N2Zl)R{-28O7~;T zAbr~hQ9rhaVfVKpN$ggt^kg`gAxHW}AlGGJ3KN4fsWA0g2EgS{!c2;HAsXPd#+%!5 zYHH~9oVKsa0xM=ON*4d;?^(J0dQw(K)lTU_U z3RJsk2r6Jf`fLvZ@Y=}LECQ=VW|CEU`8<0DQQ+=1S047&EjWA#Jpf?}OLZA(*&X`7|oFaNfi``aY5$WsVon@hHi|V6|yvOJny#TGX|H z<7Aj4+d;wcsCYE^)<k>N;58tQ$v+j3g^R+e{5!o-$)_ zzCy!y`=p0Pk;YVU=A{)JROQHr*`qsvr+c?p$l*I>qH64m#VF*$a-b-}a*FPI_)bj4 zD~b0>Y$3)#Jja~f{i90jB^Q{b*YLw4_ zP5i9V6~|N`h@qVePyA*vtUdTmg<2JHK(Fy@PXnNNC2!6uTQ4(2mO$$~X^VNAT%RXG zU7`%$a04)~aOW>n#E6}a&lPAfNjM!#B1;i2M1{1i6FK6jU^Vn%iMsIk^@5twL@s#{ z=GfAd3B!GVxV8tamgOmB%GQIxnxa}>(s|KSH6b7T0>JP+cdZ^DkJXUV#S{>0MNu5m zz_#mIjr$s6DK9GM8ENYlhPPl!V-zJl&Xx9|=2)azF01CIHfI<;?X@@Vv&E7(9x+l= zC)F-#WMuKMY4eKYleeeE+7(&O?%h3;tF*Uy~Fd!gt7e*p!`#6@Vy_Z z%vf1`yC0nrrmzdhZ+4YXrh@b~w&IvdGKk;dVuj*bU$u-c-SM3@8{!7-_poP#|ISQQ zLWBG|72#xl_dkd-)3`*IJD{Y+Ez27432quusd%GmXt!ayCX~K>R0CB`w!uNDHnNYv9`L-|iJLawc4{62Z4&_@Ht2pi#|2-%nmK3#Sh4kD>;d%(5-AdA zUuOYVJoD6S){IY^9aYb>hg7QWmOaPhtAM}iar=F!t(vv{WWEThhg0bSFPYrr;uc|F zRw>5TryEP#?agkDW0QfQi~cglbx4yl#ac;Lh-YVd#q=w@vSH%aSe*pg3Q532>FHd2 zPOnDtg7+EcbSdR zVd3V{uko<3vy1=VGeE47!>qPMB(dOyrL(Fz%(GZPl-k}aahpzBTOB{_EnKN+Fa5)= zvq#`qLSjXUg>-0@G#ZoJu@usL`#YM(a3I88S-zSkLMfjs0Z4gmo!$oKkm!W)*(q3OhGr$b{63+LQf5a%Idd+1K}|wUwY%)>i;amC zR7Ud9S;tMiL>E#acc;^S*2Ngv9V3eI(h7yK*G^KXfoJpw#)A@J7XVqNJOTO`9Y5mc zToC;xsjNJewMJ&sqH+%ejN7M)@_n_bF^ zohDBm&zS%Gg)#U{NzYfA&m}P+h1;@hgkQ|bBGdOf90Jiuu`bo83>u7rR%dVf=O)V}tbM5h6tx^7R!}VlgBs;m}KZnU9C{H%5@c%U;FaxZ5e
zM3&>}lUe$T&QQHt_zIDU=d?#fveGyHZzVXQNg{o~r(lCRTPQ`DCj5=MEF%Z-P`6{1EXkmVgI%yS&<56zBKY9?ixW~D8yiI=HcJEm7Mt96sT`I** zoQK!kz2fOk4M5BUjQjmx^o+0p?LHxO)~6xYuH*?FH%+bTGpO{)omvBsQv4zYGmlaS zxV7vvC|3_+%5;T|KNkwiwhyiswDLJ^b;?ZMHo%s(`7riB@t;3PL(R8=-5jSYn6F7a0|24MG-(d4_-rkH z#=n~&Mv)oTrQIbdji;fmm)cLw0DcM#asIC)0ZrQ66k0!w`vf`e8cm)b?Wbz@xN;b? z*k@_?jpf8B(}*;COoh%UL6)D(s?G_3%im4O3h%aHOhsz-a&z0?_~gG1oo{JWWgk^1 zM$`J$6u0wGIhtLeZPAnR%-e888rlOu5A6 zTuYSD>y_Z_`bW6sHutfXnu7%_&Dl2`rZ`ZjbHq`?#vPq0>741BP#?h`#r(~Pq0zRQ z?n4rX*U2;izQ@}qO=*Ez4q<5;3krk)njEg9z=jQ)skl30)rPB=sv}flqdSVAiOPpr zb%C`ZhdJh%Q=$_;e-2R`sOUaP|2GQu=g);BDkjl3&azFx>svKK867Qrf;+B=is#^6 z#o%cg0t&rTzVZHZ9gCOYj`?R`?9V{61$Ue!_lX@;6pwcjR&+BuQzoEK*Xc4K5bkoT z+}2gYK8*R{r4B~qq3IO_^h&+|Ujp6|V?llB~Zzy|S@a8DjfDtDy3jxDwo2Fa35((Lq@1+ae#B8UN_DHb*xu}&dfq- z)Nv?PZq4V*TGM)cimKz>FxsBgO4v4Qge3SeTT1t~ARF(@EIV`y{q&q%#Z3l|MiIS7>Y0b~q)D$%qB+ZG$OnMKbOlELJ zqgFtv#Gd%m+4We9pm{UWH=w5+j1ozPnH!g&BNDGUHoz%mNUEPk!8L9U5MVA=$Xk&X zkftEICnf>J^}-Vb-Hf#M-5>{lrP4~xG| zBU>^C{@jUi!f8w|Nh1k;Pp3EFNA#6WJTmjIu1r9XxHK`6!7Z7ZjJ*3?@6l3Q1#kZ3 zoz6W$NqqfrO*_?n(z`*@35P9Sk5W_NQ3~RpfCgm_*TjjmTX0o!K%w`Ip80eX{MC-alJm_SOSqGq&mFv$ zPy60K`m8VzCg+{jzq@ese+)Y83;VHPhYI4j^(tz*#Bb>0QfRnc_+782QL|9VxYY+|1^L(jhcCMPJC@%$b9ulM z-T&7=xESHwk3F&^Y_^z{q1XRzLPwG}@1h+V(5vse4e;AI|pRsq`=3R9ETD1P=1*4zwYve^7r+Y##kd|U{4xqrVX`Bnad8^ z4nPl=DqIZaCA^%Xo%7GjCXRaAiskRTvFKAIfqJQ}j@+2l!N z8h#^s&m$S4AjE|6Ig?h`*~n8@Vt(awPJ`)@$VvU<`oh}*>G`S5Af!fL%rh3;Oj0&_ zN(a>i0jSeDXyD&`FEBz;r!97Mw0qTF`CN30ha-W!_RlAAi??wTZ3tv7@Ds1H+u|F^ zr(1yXKv*!9ROcbc=?4VHys!}hK@J_78zo#KJi``@6{kd;#aHa5g!)+fe%S|F3$!!W z1a6uqTik=*>nd5A4+rcQ87#=ZK^A#X)o_-Jwtu&>39s)`iS=M{1)u(za?P@0Dtvl* zn@tk|XP78S0&;%~kd{HO)|(+rJH{cuDg>;FTk?8^EFnZW#`3uCbQhS~-e0*hj&C z*gqlI)vEKf4`j1mY2kuwLyZ@<+c3xO7n#@t zx1_2Wslth4d8a4jOm72jv54uMSwZo{qLcRvQHAF=z*ty#Er|vCIpb)l3@;rfq|+1~ z;bjmp)!iK|Cwz4O6iB|;Uy%le4d9z-R@~`}iS>-%PG2Im`K<6@`0pzd>O55{!b@!- z=POk5O-`3E9|!FIUCtB6-~t(ffw973O7mEMK}l9DnC9kY z@;6;FagV&o;5Nc@L{~(LtQ%fqE|-jKX1BO4v8F;a0lpmE!7SHgL5QUN`K95?y)n;S zCSoAr3FLl|nXuZ7IaQO^5h6K7RHdu}Tu{$^0KVwY(RAsw-Jz&UsJ(K<74gjiaIs`X zudVbkBgGw>h0|;P#uD;-<7trZkJk;ghOkA%^k8VWSF{n@K+?ki`HP8&=|Wishrk;T z&h*-Q#OnSsqFV}5RImS#&SVp>gd>G}%=n$aD}`bjA#PF0EVCwv!HvlWl3PIj`}oyx z^JGXf(|WXR%^)K-q%b8p(Y7-QahY|;5L}2le;0-UrIU&H8l>aEn#|Mk6DUB+p*gBl z7VPokk*kZjZk=Z6)0%)be~J9r{cZsEtIRK7V8x18yPU804nK|Fh|F5AKKQcw6^urn z39M#V7@zG47g*SEbl-SXvxVcMA*A!5FUuA;Gt0yqaAY>;i1c#YZF*WfSfP47GTcvcUcMHg%+r&>9 z8Q%3536(Ldgrzp|r8*ox8*z0MzcyoA4hkbvW-Q#4dUBAJqJjku%zwSDAW*MC--b?V zNy?+l_*kRSCeXjyCs*+&+zyF{3+%e6 z(0s1ZmDNj7p0XGPCJV!A=urwkf;k6yCaMIvSI90DsE46IU=^$WNarEUSJuzJ130nN zZOyuPcyxlcwAzBZ#t7w}00Ao*vUiM-1(2t(x>wS%``Q*#%G(V9gXc`X>P=XvcwV)9%bqm~4E;lfA&Jh7QRZja=yYAMAc5=kp_B z56`J!_boLf^lxSe{XGZS^he4&Ai0h>3dx1v4}};fAjirjCkSz0gn6QMs}u6;R!5TI zC2UOm^pHQY8yuUf(5rH^iD8L4wZ1rkDksy4AN>w>Z=lb0EGUII)A8 z^*CE&Gdti3@ky}k<^6*+E5^O!9{!(k2F7`7^+|V!sz{*>CgLM-a5RA(b-gZ!=1oOU8=?5}qDRRP{jeYE1)g#{mY=qY%-A#uk{i zgV}0F7TOUJ`?d#w|A|=EL8o^5tR-Chl=3A12j8M?IQAvt&VN-1LB>0*()Jm9J z)OeK_>Qt1^Um#LU>4PFAsQeXe?@P09;% z|EB#(O;D!+`|!(yIhjSRCav@~-Q2EAhZZw0!(I=~XZ4I(WP8qf{O#%rkVw#jNHm4SDa>8Lb@^pg!L9(T3K; zDVI#{-PC0fd0`?B=K<`8%AnE2EZarg4-BUfgR2V((;N(e^Zdv7FH%OLKyanqJ6b+# z1~ag#j1yXUoT)9|32vS73mdSto~|+j1M%#-F_y;H>1am=a~$qhrO?+Nu%olLbK}3> zf}GMu{|y28>=$UTiz}@_jHgK7VJcSqq&*_CL~iCl)Luw?0SeNR-MrSiN;uW9D&yeO z8Ao?KMIi&kCCef8=F8){K6-#L5W=3sQOBRACID~q{2Mis`;~}V-@|=;1k-#GK&V%( zz7e9xm9wX<@CeO#2kAgLE5LUQEx?SDc)UHr1VFUQ`Qi|`TtwW0Jg=MOzU{`|>Ok() zz;+9OCQXSd>XMc%Dq$1;%~_!u`A1QJF=<7{zK4HstW4L&3K~>SqLgm{lX*P8I*8C5 z{A8i$U)@U0LJL;+<(l4I>p&1_$E|0#qO;!H{-~!;Y;1X{MIYBA()r|d+=B~E<~oc4 zYy=BKFJr|o7Y{rnv$g}~2{+nWLtGjD-|KUkG%#r8H!UJK?wkH4<=5=YslbWMPsR}c z5KE{D75USjM2}`6Rpi|>o);sFcQi$h#l9FhCe=&JVHDXunR(N+kC#O{1;_ql9l?b> z4eY^;D6-#o9!u0HWUGk=voYoQsCkkfF8y$880XKS>2cszwasWWAlXwkcG#sz!?wtR zm=87Hd}@8lBe5(VlK;rz`vf>%JKY#f?Rnjh7!gb9n)Fj=v;`&<9s|6TMVJ`k?d9(9 z5t0`WDp^;4t>vN}^*Bc!6OM;AZ~^XB%4d{~CZYbq!S5T~6mnr3ESjCFA6(3Ftgzhc zGRU%RxIpiJfh+k5Ieh4izXW2#?$OoxOpTXgJtn9#`We$3gZ3&`>%}bqu;x26C;M>g z82KF;#HR~xKlJ|gtH_?&L&9#kU-e?@@u+HhH|65xuHw^-vI5RHAn*gJVn&;A4?XAI z+CxK`xKv(1BcSCb%#DVO<8^!&GwqJFd>zryD>Ty46+7Lkl}66invW>p5qa znNCPkH!y&@qKqJPF^qrJQmVM@eR6Ku*sS=MFo)Tqjuk9W$ENY<<_lL8G{X`QOP2s4^OZF-h~K_q>2A>m5xvd8=cR9=6pK z`wM^Z?LDX)4i?07n^Q%PLVVdawew9y>Nhr@FuZzINHxiQ1;)%3^`~c^Z-Kl~3Y@uY zeF<#npYU-Duhf|x5s27?pXE>ObH%aQ%fh-kS#eR)Zaiub>C={>wM=VoBhVOMDenEt zUuTZpuUBH9nfzD{8(L^K_^O0LaE=xLxMKJNYh21Lq^KKru{!3g4|(eT?7 zkeshklPwNad;M@+C|m`zc=hfu3DG@Dm9o3o6VM_}#{xgU%L#2rIy?ONe4 z416~5j8TQeh|8dx2?`phaMuJPk!yC_^^b8}KrLGz}kr1F? z(**X?l7BD0q53)a!z+D$g;CzUD>m)Gh*(lTUA%gcb#o1s3|ES&aReiOrf(#5pV|Jy z{w!J`Y}rq|`$pkwBMXke<=5fbzntl;A(HwkK{TLqnMi8zNW>j`3JHZyi-max4bdi>BX|C z7E8F(rbf%%@9Q3(%#$V~Fnnp7WD-rMl|O!~Jgl;Vs% zuckQTKg|vokMZ=R!N{&Ktd(DQ)gEC2h6`V(?tpQbxf^?z7lC=b)1JYr3cb2598Fl> zAX}xk)b*i~uSdv@)TK3-jg=DW{vZD3Z#_8E z;TUK$^=BjXU8315F6jZYU%tR$M~#X}F6%dQ|1vumc1I)~&LpeW!C}Bv@2O{4)`#K;4f5KMiAn+wQKI%BqjJW>;)V#(|v%$q*_u zX9t&*2uw|c%@OHc!#kB4XJK3RRu*nZgx^-SFPZfGo|JGMHAko|r4;2;F;i6ZaWx=E zaHqs1VY4CZ_)yam+-cgz+9DIU0tLejT~T5OYJyd=Z`>YUWXcM<;rBG(rgC)n1*q5> zNY$)Ye74)i8}1=)mODY~i}3f007Zl3*@$50T@I`h5|nCKk|3HZl1z1VcgOi>vKFu) z%r0F?h+XZ8buXkNiuV5R%QX!&oP_bIDt!)~a%NCZ{egYMc1UJE0mAo%x|vJMi5eF1 zFoUw3#3D#lWWW|(_(5#Iq&@p%By#OJSsyY-3G^xpI>7HfVZoX-%yuK8YnHIK8C4fR z5~6m!OIARv*e(1m$&YjA2LW&By-P!@%*!)-x5lC;@4sm>ia<^p3ES>lHCQbL^T7e_ z1@x3U9u}UI`@$b~mYenVJJH5t2_ZukS*e&lqSX7&RWnO|hQ6>zjfp>SNl8EDjpTS<9TCQCERIY$qz=_%ZCcY4FPP(tWaJ2_#Unsey~MbfVUr>08#C}=_G zIGW86zm}sz6T8@nk@>1Lip5nAba6IqmW!}GGDA0sGTDk%7n1YVJuDlJiO9>{NSjQ3 zeoGIC+qPRq(D3fxfhpcS9K#F!--&@Lvs+3pfUg&H$9#OV{V-Z)fcOTcTV=QjVd&5O z0VWItxiPgw!Y}j4t%kp|5#^?u3d$No1asz~$)Jd?@1v(JrxfdxX3(L}eXjL-vek2b z=@`R>61uQHx(}<&%$O8!Z1+5~8G@L)0>B`cP%R;4D8*qGMvwEC7#|e-IIr(Wfu38n zho7~H)diKh30o$goX_k9`8?XyFC41!{SuC+m6BprncaACWx#B=^U$-k>?jX(S|MN( zj`LQ6pbE0lU%Ew9Rty(#sK*VJv1kYIg))LMH5QeF&9u|nSQ}YGbz%MQ!+b1Tm@A;^ zD8ksctqA&KzH)u26{?e$QOEh|q_RJ0@K9X7d{m#eRW^}+WWtu!dv?#6PKf&KeM;|I z{*(&{q~1*4e{h*QCiqyY0i$Ml@O*ck$g%v-GncM>rMCyDD}&Drw=JyKx*4RnL=1rI z=psH!Q8095Rj)R&vG*QKv|P~-Gs9oz8<5m0*MAvNYFW`9({9^50DG2j_h_f?KiG|v zlc-e<%k;EBaNZ!DV`&~`3+h>YuH9 z9%G`MuIDHEA4@p7E3y*RkS@Ckfx3*d6WAIJ-l5;LUV;X|{z%9_lg6u{TH?p%W%a9( z>$dGZ1TWF1noa2*?^&UP1X){ypHBQWGO3SJ12RV8-_WmNgQ5PIqV>@zJAt#mcLUKh zQrYjdV96Mx<$DE3Om!FYk2vwql;7%d!1hbAdVaR+&P^mSYmw zo^N_($}n*RTZw~u*Fv@n@pB?>eobueD9@8AmZ2wVn#h^NqxbrLznpypXwAadbWr> z6x6$S(TRDi%=LH1z27CE7xYuTJ{*wvGgNg#zcXmwy66Xj0G=ZUnVPKTSGVr=E<%vB~bGf2uJ`#>#}{^#{pN(zfdC zCueBT`_Pn%qUu-Nrft@XH z1>JvdRZWI3DU@G6k!r(w;s!sSejo6&WH1EH=!cAw#2Q}bM&4D1(8Ge??A+s85R%*Q zSdPj^zM*6}-iCm9>EwL7q|$o;*SIn$+eNehsK(eTw_`p;CmC6yhbGKd%F-!VgY__I zM|ftXXE?sE2LVF)9QEoG3zb-}trrCJ=jnkn!_4$Wfd(eW6ORu@d1zh@qj_J4#l9Wu zNeOMq8otR9;T-ZC2H7+B5`YA+xPu)^mmsYQkCtpWUEMsnPi!L0QhSrj&s&z^)-#g* zx5`Z)cnRK!zN^pw3*9Sh;2ODIOg4!m$(r223cZ`}Fw?03Hx$2q)8b^E`P z#DYLTH-k)m&@I&Ok96ZhD@~zOpjTf=Oxc?jR<5i|7zzEX)=mZkjtb8SOk*OdHmlIb zqFd`@HC=R&-VDrlxi;-O4Ap*F|M<5^jcpXbuHx%l9|;hMq0;oW74UlXMvg3c!h{_iKRCf6XJq;};B z*;0-3oSPQpq+(Am&7RzlVKO}AqD08p0#2Uk6sQxp+}qlD#|y8?8v`Owtgh8XN-Z@J zMD|#DVal5&T6S3z(xI(kVk} z=nT~NJAbx>Hq>h`Xs3IZ80^-JuCGmbmg=_Cu%m7~nptm8PpUshD5=5GBzfes-3VY} z?&s6v@7NSN<4~r!v`)oe=3S|Lbvw;gnBwz&JJkzZ;3Bl?wd^gL{k>L@?`JoZeY}u4 zQ!6Gs9cxO3ri;aa23}{2Kw7qjz7ERK{{B_&pDeJCFNk}#ltuxIsJ97v)8#m|H|Thp!_L5a!_?V-#-ZrcCoc(=4G~&=FODuepuHAr`l(( zz%D(^ku04fkHlC0PVE7;V0IJ}WSRJDY$04=A5v(Z#{*Apag|AVW5dze)uh`)m{^Te z+WjbGD0B`?$tHO9V<8b76wGURn8Q^@@F6mKAvki3%Bl-h$Aoo(qosZgk39?9s)QDi zNTlHjf;xd|F8keFvwh5ch_I%Rnw)|%7yu*Cu%2F z#@rvdntxwU^K}(6;IBM947bE*|H~wF){lx=L9mNPVKHe(6F>C$`^XQwR%VIK!QWMw zGcyu6PA=4?364zmVTSDW^qZOmFRH{&?}tiUo*rxW6`Y*6THO&!%JRP#e!yl4MsScI zKnPwnE>x972NBW)d$a4trFBD%PhAb5!g3c)Y!i~PE5pj=II^}_ZFXLUlGbMG#J-EV zHWKk4DUqk`yhESE0NCjjd&_$&3(*xaVQiZmMBWw~wOoOqAA` z^o#(`dK;ly+W4(ZDCBO^sZ|vMN=Y-9jIQKl$LQ zm8e+#0f|b=T6-6(BwWBjJHPk#TE$8yW&np@)w`KOb4xikM;j{8yiyuYfj~V6&;Is9^ z+^h2mjHnS&=d<$_cA=?cklCTllTtM=yHIo-L20o@rjH6u&fxRwT1vsy(WC7}jHBJd zrbzq(*Xv>K&O8CO39XIi&c|xQbN#3V9BRE+5FQV$)-0UgzJQL=3r~baK10J zzy2G(o6Hra+uev78tW&i1hZTp=EB3@*+88%g}f#5ni185?mrkA*hn|8?*M$Zjf}eI zYv`cYikv;~gA|g|I72JR!Ms*^r_+kVMju2{ALfEJBDPwhqaCiwrTx3uVdmhMyHh2l zkrhC8N7q~&r9?|hZK#Yip~Alo3dv#g`0qH(C>4$F@BhkDlgDe4Eq2?-nNV*NSwe|{ zh+;PdP&jDk;O6$U?j>1be z_Q&SJ|Kl?nV*#BK$KwaTqgN%lH9AmKGZ$M1xep2r@#6b*N{c@yP4D*7>qSnRyE+I77E}t{N z*51K8MEiKFh5fnw(~qpDyMU25Esba&=*zII<2T}}%Jok`5@+|~(glvYp%}{#oN-~} zh4k$w{cSn&*=6RPLrh9{dY9V*UbA6u4U`aHXAWi_U z9IKr|xr!IzQ6Y>a5D>tVHakcMy>G}OFkue%W(7nQE4j|%oFk0vRB{bO;KM^8uQt)~ z)oIb7+ibDX$|z=j#t=HuSOYiFqIrU}=fv#+1jkx?V}4k7)%Dpp$JOgsXr9S8|L-Vx z3aGADD7h=Mwb}AeZg)Kaek^^RfLpzc8ybiwlU(f}q?uY1_U}zFi+jW=Xl4Z9xs3>a zRnV*R)!rglaN~4L@!L*w!^#u=DVxJg9^D`>M)p&A) z_c7rNf|Kmy@|U2+S?2&K_Ol8M#`gQ3k9J%{?!pz6mac8r+Y4V~#XqD3 zjtSTr18-v^lwy@ft?7}WJqS1fcE;xYI)|PX=((bh8et^c>_cal5;oS-iLJ89De^F{ zG!&2jzG>`t;m6c$_!{+wc$gaFsFb-8-=1bOS$sOJLnQ2B^<_9HmN%Z47cBx#-~iSX zc9O=H+r^&YhwDMIJ4fPEMdzopb!zRsjb^Ws5t%K305bv#tQveK6f(jJA}`hri4!G#D2e*U4@d)kOZng|+xdBUx$fWAfA#wE|H9k;r|icOva)F!iR2oz+6T<c&L$df)jsxDo<@vDGE_q$T)BS~ z&ZZA|De(=Dl7RM`FP13nS6sQPJm2<-z-E!~lI#I`-s%U>A?_~|b`8wow#RQguXhtz z632Q{rbXu8mBZ2ZWxL;MHtx|-?w`hpR77Xl^CL|5d6!0P!o_o8+NYXI6|FZbTD=1c zgZCV8VF7nx07K5PY^yFPU{L`+lU`;tYatVGD0S(D^sibr9wMt_F^zLD><=Hiz+H~) zUzUV!GiK4SukTa>Sg{^8n)^((5?g|>DD}gx6FbQLdif>73i>s;pmu^|KG{0%0{DJ6 z9xd1@>QN99K)O<_8eziF@%U05Pn2NX0*dYkgy!OqFI_cp9w~{%Pbwh zT**ofEgZSuWpZ%LrRsM!5A5hk-pgUO7V@mkMQP_`QnBY`K|B@SHx1kpH&DrW<~Pby zcxA~~fHG5s8sbI(?yRC`?2Ac*(T?M9gWHjiuUX%Bua3IjRFn!R)fR9PJs>7qUO&6)B0e~=~u1~kv zo_IN8ADsI?5I+VRT^IH1c5Ks5+9Bf+h56#C-Sw9<^JpYR60_oZX*1-V4CrJjkJ*5G zk59tiaKn|WT?B(o5NEoEXEyF7y(fDMDBeZ1cTz3TD=+G8Xd!+NSHLe}LqAmBWHOkB z>(m01Ra9J$i=di|b5>-BpFa0N=9>)R6Atyv%i(PQLQR3%G*}rd{Mq`*jofDh+b`vT z)A9#BG}WEcrWTxSAG(I3wf0<^)$0Dh$2Y9rM!XD(*af}j5vG;2Ty*5bvRnKohfGvM z5R8BJ-(!p)MuTZ34ymeGcJn+-gowpBo%}eCbW+)!1V^_Jg&0@(CQp9a!mmg6ji5N` z%odQ?ck~ONlW(xR2=J|@dl0kU7i##@Zl&8 z<$JGD%*O{4jv172hv7xy6a`%H%vYzLg+8(lp)@CX*!CH3X=}(PIt~0w zV`Ex<3gIxj^~YRcG>%V#peHM1>?*@hP;EHu?^JDHH=`gLrPH837mis{%r2gqUc(97 zejAiDz9<0O5|*RFR|{3$$~HRle=^})#hyR@&&KDGF35e}KCUI$Z?xixNI^3`sVy-{ zyU+j9>eo5*^u++9lQO{G?!10TP?m(E2rC^Z$v@4XqPm2n4^$_!3SL%5k>}ti8bWHxs^^b9{7y?H#4jLWvfuBzyMOF)CT;W2u72ASL|@_IJD;borBGXNc+7)c zD#rdX_Lj@b=WY8_Fbx&tdtiK8HBNIbn4JtgI8sWTxx2h(aMk$cZi|hz0V3tW2Z)F0 zTBOqGynkQ_owGcJp_rT$NESHreYM5DK&9UW=eV+D>@IOiGYkCSJ@ww~V%&Buvu5NMoJ(JD@u5awK2TKU)DpM=?)VOwlA;Ttj5Apk7`fa9F%W)Cyvu z@p_dnXEf+0J`?bkBduL|04CO!UK1SFok5DBN2QDqYUN!-5w!R|;^sjm+(QgcA6OWc zs-@hM@c$Z6<0SnynLr_kfx6!v5dNQ*Z`y*PqDg{r-e4t6GTniFL4X`U-!XGjL8Mm8 zeH{8aDHAN`)?Dm`{-Y%+Vi&le1q%3wkIB4FB0Dk}+?O1n*W}ppG~fLQFzv zg>qO)WdX#dbp#D|E+MHdC|A*vfq#^5!e~whZL*9!+tF8WyqoMU$lKhM339R=teDo& zXMb-zbZ&I(3DOZ0g{A7x7$O73^r7Np$4nPU>l<^zQCcAqkII8O_5Dla^w7b876d|v z=+|m-9QCkB3+Xu=GJLg6b4)h@#lj2xxWfe?ILt7YVV+AKQSI=wGvWeL1M<7Cuu@)z zGNl{9mj~;(_-Kplwkneki7D>(?o_FjI64O`hgY?}hw3l*JQeubHUUhLTtok#_zr@{ zY6p#`8B*x!f)9neNq7iv%$Qh9q+DwRR|_-9#|EVTVqZmY8lBgR#cxa-ufX3xTv-36 zfbfftxrw_8>mt;4?R=!`*2$J3t_cn;uW+Xo--i&<(4e`x`X%8#AM&vE-FJ4`5qO@@ zT*gq4)a2IYg|q9;-g&QE*`Uk_OLS{U4+ulipyT`~Xe04HFkIO*R{#7Ha)RXVl0A=* zxX@EB*Rf;RtU!i)^mBFdbuGLIyoAp2{Or{@V9-~aO|~QO+FFp*h8YtKW!~jlJCbJY zj@RekHE%IzcO3P)V%JzLc~xYvnFDl=L2}*#^2sjS$dLCU$t|x#ou9A#oPhud0?s+v zz#tka9iXPdbhCki>a!$JZbHn%P49wY>=3IruuQ^b;G{7`#e7YjS1enH(G2+-VCkpE zppteBvIjN45V7ijyR+#M_q-PDx}oWJ7V!O@P`9-jS)N?Jk#O)n$liQVZzj81;=A{! zTVHS5?XMfF+uUA8lG1fZTJv175(-w86wi&HrFYmW7FFK@X8H*@;L|dCD~*hnW|CnH zTY8F+MgE6a$LqKgm;E1*nZ(grHdK_A>pIUr^lm#@Tt2bqK4sU|2FU^!^}5;3#<`z5 zPaC)NX{tJ@JjSD}hyp6K4(D5K$Qq-IV!bRH=YePW+ zM{i5xTm&r^-oWIMsXxF5l{>s^2-a&50ca2W!9k_D>9}fVx@fw&I~FW!->CS{wlcw< z4c?9r^wndPo;!Z-I!ywdTYW_W*kb*PX8|}+Qxc~$A=;pzC~sYk%M@e%tvf4s7*_3r zv*vXgsL>dNNNxihuQ;$PLh-{;u8)FcoB$c_gkl676IQ;|mB~u1X!*Qg0jw!$+g<~O zu+Ija)!Mtg+^Eh}p^`iZe#b?5i1*y6h}nq1r`ml zHmCZ)w~AqXqt{6}h&dhVhD!B6t^CO*_{oO4QSae*cHT;ln4VL;x86@A-l)X#tP;`< z>UM_DF|jgFPrv#f;IGiD?=|I6Ka6f0l7~vQ&HR#})0r_5rXkE~JCVwL8iXH3_~PQ2t1N4f+8zY-~f_{d?l6g$iD%?lM?L>WZDGTtE@D>rKRF*eJB;u%!Ns8;(cC4 zBAy8I52qoNWyKr!!V~a<*o> zH~X%tME3Ly*!HRK9b1}3um^Q@6CQtC$7y>IZmu)jAM~!zIdT6?Q(F0xj8(|b^bUV$ z3r_XX&|#BjDBa}bG4MG6Ce@EtXabru9}i`d@EkcK0nzh&EoGBW?FPt##WY^)aw5cV z$(J_lz+pt@>s~owx=i~ah0<9@#%L}s^r$rhEn~r^dLS2$! zwk=P)iEg>|1{gb11LIVs z$wi#ND!0O_9~#1l|C(x;EoKS4wmtE`vG&6LBlGU5`{@Eg3axsiPQ$`BJn@VCYYFn9))QMIDA==7F#rA#z1+-%cki6}}@=#eX@N0QW zr(tG|$ODp@jvKW_6=@RNOfcN#|wjOt?9UfLP4vKFG7GVIY6(y-2}jw9ru>I_l>uOmz$?j!Jn|7;+pBx@vgEW+4}3D2Xso&%m|T8RGUJICn!i5!eJP@ zjq2M(r-O90GQ3kb%_rvd$oPg^kNQvfZ^9ar?EWXtZq(GHrQD141O$ld0SVX~4WvkO zKJ~sIo3LBb9^y{|wg1dZ-(Um_>3=`aWt##4?GtVh6(~71S#E_p{_8L9T{h%Oujfsv z?Rlo=gqHNOT*aZb&^x9+xhbWUxw($_(5$d?1-!i=kI>563G?@ zMC?o~MusMnT!dwkD-mCr`;Ar7uA6oH)U>CrMR;x&?$Fq=tp7y)GnI{tCC{M@JQeJ2 z*7IE%Zt*h6fh@p$A89?DblxIK&qX@tu!4R2R`01AU|~dmZ=q!IVl5hxz&0~8YBz_J z9&$;;zoeFd(^pMt8>KIG!4+U#EgzFyX0ZGjVLu976j)7UYXH~x-^74Wtw#@X;B&+o z5H28V_J2!gQC@(*sJr)0ZL5lQ9Qfc!Il3HRhiqj!auAso#PB}?`8L-$r%293j}m!+ zsEJ+tPKB-McO`cHSD}$X`DVZ2l>Wwod5|iLfQ>88ST5T9QzMhDjTGLtxiYm>HT^rC z(>rDYY-pU}F=e_!ZUotsF(==c0ARl=DyG1~W8?`i-F9+MJ?vLn~9^>dlP#Trn`Oe*vpub|JM|-j7@!$xM;XKe}E|^`l3%X zxzVDG`nS38zFxfJJ!uH3hj8sDvmIJjjvbI-i#u~v+lZCW3ndCPRaqnagU%L3kM@Tjq8H*%E7Jy$1E+bH9l-naV zJwA8)y2!x(LN8u_xp%9vhgJDFZ}PjnYZqXNb<`&l&^~cQ?cK_g!XVEo+zmqbp?e1z zYe%6a{9ET)Ob^=C3hkm%$WyDeB}|JM^s|c}3lmbv)XukK1Lak?2lc*3eRwoWUWC+I z-1I(-V?Z}hgoe#I-LGi%`{HMMc(1E&jdf|;MS`ZsGIr4ih>C&0PBb{&N(7$EhnGh? zXR3e{SXt*m5yU^$zka^Z-GO8`LF%#oI9m_%sQk?LuE1G^ATo@^@F*{_a{To1*bcZW za9rpPq0)zYQ={BRHbNXsrW~mS3b(7N}a>ACi(lYcmwAdB2`jb5d;1 z?N=n&PnN)eJ_^%i^o*k5?%nqjZQPdQ7WO#MtrPp$9MSG2OAtk2Hl?N*!zkXLE^EZ! zC-E&!}{Y+=Wkn)&>8`IS>bjZ&o6|N#_V$_)DI842P}YQ*r|>H--aC;o*pK_ zZ+;fj5`BpjLPt?dWS!ZeOZ52y>Wi4AMA8r1tC8Q$JW2FZg)Gf_QgCQ#PNCS?v9nlI z1hCNwer~`(Gd?Otxd4V|_GBzU3npAld%Rn1o~p~>C)dd{Xd16ZX36LztieL2x{dgv z=4O$jGaQnnP_Jff>;nt=Nu9cBAfZd3#0+eX#AxU0oZ`9=&(P3;#E4iCRifd*B^L)V z`vOv`cJN`yHC8hTZKiQ+U_cG$-zoIB9UUvYY>2DTaxdbrHpEVOQkIL6pdS8A`z520 zqch!8%pqDN;YgT^`aq~JZ!-tWws%H<(q;OI2v@<;1u-hD}ga<2#AkuVO! z^@G@9Go$Exn&vT)>?|1W4?#1v0t+jc$@f@|C5rQWwh0kmnEV-e6Q)5VE z`K>{iIh{=3q5{1qc;a^__ygHJzrW_g66(W!gzwS~_KSIIg%AB-c*G$4xWy%0;+(bU z3@6SXA&|?-o*Iu+ZGghr22o*(w5>qG`Vdc119OCO*kUARe5@sLq3*>gZo_S$Nk|DD z8j!(j5xfu>KbGFfjpuYIJF+C7JmK&>vtb=6E;<-(_XOYBl`1WYBaEq`?SV1kCRmk3 z3i@hv3&`gcZfihFTw+Ff;-WCT&27&M{%v3|TW(h8{iE`vRBj#ZG^a(D%6S98d_izL zY)Hcr>xpd)zlo;s0-7clqO)H&OT_eLN*5(LQkuhSM1!Y%$hpakV+b zVJMm}@k-|kT@;Me?O^DIHETRX{1i$v?)A?%P1;iam`gELAXz0xIX!9>fTn(PNQsSg z_kGyuu~r8=;Jz}1SD7G#)%TWRoO}_RC9yHcd?A@`Hw{j#haEnC0ld~FLeDq|KjR9Y zCf~AeDo7;|#UP(de9*QWHcrwKMzT=x>b_FOQZSpWYdK~R)ZU7{>0m7ptbd#-<6Mv2OOVu<9Z2l4&;Fs(?lA+&Z4Qq9NnTTyg=xyRtXr6CihOg^J&9va>u?d$z%eXp zYg^KPgpMI}GV+X=+p^B)d5)L|YTgVA-dmG4a{y4cF%oNUfNpaR$3Hj5a&F$1TYYC< z3tDa-K5^2tsDF3Sl4e5+!Y~^bW^w!-_p4l@U%pkUKnGOxE+wu@Mquc50$DxJmCV5Pahp!E1Ew-E?L3Lcso~?r zyZLybkaf!+&R1_EB%A2(Vt`@@F6Ev$jSbhK8`*gc^Z!!$v+n3fWWwpUP4TiU=tt zN>nAV>Vrlv=B5|?Mi@xxAfE}*?VopoDNpZ0E@G0m1*lj{1G_5E3F1|Mkg!o!Gl zz=aJF?^`)-dXLhgY$SUbIpjL2DsoR0(iD42VbGEW&dRLSRf9KMXhO&@>l*^}m*qAD z_vWxK5@)GddkixQafP*Taxl1_AIa41C?Gex%Mh3KW8@3@M&~YA}UxtJQMDzB!V`Oqe=!CdyY{%2y znc%%gpn)J6Q7i@ONDj_0vl4hPNIR!`U$Jp-Ua=u-P?A6KFleazoRAGLjxZvig*3>)Vtyb&#+QZ@e(0@8yZTywLP1PIq4@%<~vti%#iF9 zC}naTe|33Q#qPo=2;+7xB@+hB=O(7-s}Nc7Rm2X*7le427Q6Lv@Z%|bSN z^gOCI!Qd3SdBX~%p-W2B{yIbP_J^Mqc}&{&5dJ-8dLn*^f&H`6y*F=>GD)&1w!QQF z$fs0%{ZOroRbsGbhYXxnwTBH29S69{6$6ptp#LHT6lAbdy*_s8(4UQ%OSsi`!Ln16 zG%MLXF9Y=55V1JGsAxlPf#)j+!sA+|$?XW7owYa#d@Ij1@uNCJf<-G4aVEVwE>NvB zc3;zoBkesJYeHqQ$=GWUtLMj_UTknHP42DBGjjM12zL=28LWSF%FmX_qyj!XqR@gi%*=9?R_d0~RV4(M zRgqkeotxmsfEvW!Y4eiV(|-F1?0wB9%Z0$hBW)L?vS>e-mc6uV6J#uEi`S(rNxqS2k5whJ5+;} z_J;spQ+|U=chdhqGvN-!_IhDCIm$8JEr$e}2*kBJS&iPGA&rMR`hsbG1L}ILc}iJp zgwySazD8;nb)%8Eo-l{XolBlh9PF3=zT!w-oCvH>JVaU%nKVo<4u5;d0b2Wzmocmxp~;qNt++ z_FHE?Z3SHtwo|v6$PUb|digq0v6h#xDc5_vLLP~6ataIcqPQnK$9;4MV;GV?3B3bu zsx*|Y7jm^!S_?rp7;+!fu%7`T4BH~F=H|@O?dRRC+Wj+tw`DsCS0<6n)A6j z>t;M8sqFZXM%)#cOT{;{X76@XP{D5E{|emEHSu9KLItC*#o`qKpOK#7j;5AaLKj@im#LRw8~1fr)y0NFv&`!=z=ETF)ENP+e3#=kri+UgWFzCNb>4nmEQ2*hyQ_O z8z_ia<}2dwm?g^~cOf$>eLmrFy=*=K{?|N5h+F(3=m0Vhd5f>CstC4%51L@jQ_RB5 z@|_!Qb9c!z++lb44~ymSL||wJ{-Tf;%j0aTPFU>>+cdpTY#d%+L{GrU$u#%Y?o`5a zX+RKA7n?1c+|CAXdRak`<56rWrv&}#mWzND7<_~&kvi*7N z>kWn`IG_<)(S#OY8|4(#rEepcVysNTAA0D6Ik-#?X(QI~$TF>Vg1C#VX|40V{(Rzb zIBk<@5OLz>YWSK0%TCz7_mKgB@>|%2X-q28Sf-z3y(&d-ogf(a;l~TNZ;@pqDI6gw z-IiqaY^-Ne(~<-@H4)A~t##PCLm%1W zqhKDLIKr=Ccg27U9=3%}t3V;^8^j644d4swYaAPF)md%8t7n&qyplV&=%o)vw?ACs zrd)&wcgelEYaG)XB42H`F3yKBrnz*~o$4{t=&VIZLK5yt95~lnNze zjQ>>-QCDxKs%Iw=nL%Ff*3gGZZ7@m`ods?Ah7*h$7-NjU>z)p=Np_F_PU&K6TZne! zR^dABz}~e#D>JZ{a;{i+xlnJ!LzH!1zmD_PN-}j_sjpiKAa+771V-8WhM@02RzLqs z4y@d8E#nJWSjIA2D=`23XANMzQmaHds#|JPk!O8rj2M)V$IVW#e$2bs@jQ;j0ir_x z!~NIRq^H`zsx$lY)3F3?dToj2(R)|HrJJpGzu|c8F8~J~F4%IH7)4{pJSmp51Z;`G zSYJJQ0(IZ8O8-k}4iAS3>jGujJ3<5?{<#D`p+NoN*fuUme~)*th}oqRjR*ficYML{ z&^e;G{${W$kK#@=*HZ3qG1T?sOR|g;adCIxR0!L|#SD)X3BeG(vHXXzje*&b+cNfL zK^1@9S+~{5w7+~e!<|?S1@M8Wk9O%pd*o;TFFT!k#UhV49yto9^EXAy2#Nga+%!ba zvA7PX=-B<&;{P+Gbv!%&-q3y;kx$b|K56mRQ-l!QRR(cZfqx0*lbI8cKQc3_&l>6e zx;30k9?rBvuP!A8B#3zREHb^EaD>*t!bI#XneLQ6E*xQ`i~kX(h#X&g<5i^JvMT(X zbPTW+CLTdR!R%cY*1+XkdrSO&p05p464iR-GN?}{7vPOKA(W3z3)th+oDReFHdgTt zB5jLcGu{6*W7F(gP>$A~_n^W=1(GRO&i>BWwDq63w;tY8<4^O0&*0q0K=urZ$Rv$O zKuM6_RFYs}#thX1R~A~P*bbq6vyfF6)H$@^E@#J%N7Qx;*^75S0%bgpjp9+LCoSAl zT)c1=*R?Q$;3q{ElIN?a$sAd4vxp1mMSr}EHk;1pa1AE}Fz3fwPjy7gWTmJ#7#FKX^~@+hUKCB8g5B0pO!*{vzSqq>Mf`A*|mO z4?NHn0(3jIa=H@6Eny+&hkkvym&PaAUl*>F51|DB!_A#0gjK?iX-o%NA|BUFJP$q4 z@BvyRCf8P}TZCqzSbQUXx#&7hyc5lXY|+*s9Bl-$ z18>|(I})}cgAzxBXRmAfskIx#@2O&$(}e zt|Z1c8-$qLn=k-%P_l?ex$1xTuszMAA>OzKzBreqZ2!B|&(LzFOVlNTtgh1*qJsny z_DQ67jcKJ^sRb)O0@=nd7LoDXF#Rw;q7lj`k#Kb?MB7F*#B1QUFUYns;)ji7DF)y# z+Bvj5!{C?*%uKe@!>A|nTx7fcO;Uy@H|8miUA$$O@?j(BnZ|Y6HgT)dw2HZO{?9X( zVl>W4VL_R|DEL*m*eDeq__OEY>?L>BQtOIP?9xAI?x}pF2Hsz78M!4Ov&L)jPnx{+ zk`>!n-Je#EUSyRLc0ZTvJb1k0G_eJ7i>5I09`x8Nr@6b8&T$GTu)mWsQgD2VTDnM> zV~~p&6h9=wfnhp#q6(+Dh*-uqZ+9Ilj9cSYgYW4=BZ@Vt?QWNyoter1V)jcyZMByp zn%QEfq>lKEu14L#chFw2*a-aL49sh^TT-t~2r~OvP_E^Khc5zfkg0Sd_(fCT3@({( z+($Q+-Aq(^jNY**a>j_ z(1%QBt;g$6Y}O}SQyJVs#>w`Z#rH>1rQ!u)jhKm9i+2C~?7EELurbr~s7Z^(ZzSVK z%8R={_({8?%v+K_sntrdT9n%P|f}u~y8%@Q>KF z>vLo$d{K-)`^?Y@a7cSv0&~W`gx80T6*Lte>on@b@7_>MXE{HS)9u=GIcn12C{}Ru z%lS>w4WM?+Jrc=Q7-DMnCqZhjD3>KXnQ4RxVc%*cYHcJRw?e_My_+D z;(JAiE{Z}-fH@y}`yO73x=K=dQT+$3Yf!zy3XKHr5erNYf0~ML?eYqHm%7*0c^5a& zO@d}KW3UF>Fk)MVv+RarC*Lk66j^5d^}RBzqFrvGv1*UosexKO#qmnurh2S|KeKObAsC*1GE<`&Rf|HtRL6(ctNIN9;T~2Voy)ln|S=zSX3W=5x*@{-krp@re9L*wj9J{;CsKve6s z)i2yHALe>Z7g*!NsB%>!$?;iZPIE%~It`^{)p<&^eR^;@t#yCVBNbHppxi?~Jue(R zI7#I~Xl+uky@Rft<;;ArfbL&$cSQoHKTr#ODuwb5pP@5iH*RpKZb&prndl3PVo0@ z9u0~i;!y@HP*FUS(V(3u02j=QPFUNz3#M4=X&PIR*9vXUGxc*Zy2WgE5yA2&hz4xz zy#!hu^us+$WMG%KA$UhqY##u62-1oYsIb#0jh%amyZ2n=J0QoAMo`RjLS}Qd8GFQO zCogzzIx3Rmp?aHVg?K0UD$DwCiRpNp7dNt+mz5hjeL*-Eawqgico}0*0?JR?QF|~xDBvlriC*jKgZd<1FV9k-W zHB~?+)Gz(=@p;vDu8t9XyYpS@+;jK|6QGfeNN6?qcS`fT{)rj%|VF4_#eYCvr3kN|WE{^R8^hi`Qh zgaOq|R!aB{_O`3^BFDlgq>tq8Qb(6jj&mTdQSK` zIlp8PI}#`74Bk=nNV8wviy1jo25-e*ny$AHFogD@U;W0zH_p1+%PXmj++Z1s+&>?^ zI)E>xJzpgR*R3%sv!KKu0;X5{bbf&Toh8H7eF~M82@zTXE^*dvOQ`4z#9$Yj;6&^* zB|$TM@XP>(NZFUeG?x<1Ja6$3%@bGZJf$RVoH*P^h1oRC(%>(E?}foG`AJ1L+u>Rr z25eS!C}3XG>FdsLq>lz`@hbrds{P=1J4F>D6yT>u`Imvqc#u|GM}F`i-oW(!&aiP6 zX}~1?5g<)80wjugV&yHZ3nY;m@VFOt%!Bt<+YX_UJ|I_S#;J!$lK=vwUTmiTJ~@yO zasmi6eS9XIURms8I z64u$`jBpD91Kgf~#ZRQ%?E?N7;1}-IU3w8~6&y0^@0sdv-%&(F1M+Re_bd1YH z@FFu4wGZr&0{Ep^l!Gg6Fzdk-)}B6ifFc#jjp8;%Lo~kbC64QukgNwZ6phM+u3u69 z0qHRH3yle4g1ojFvheZO&kr<+nOeewzU`yJ<@ zm<&WpR$=tbun>=3pTL=#v;YpRT7m~CXa_VSFA--2Kps-zm?JqId9%{C-x6C;QmzuwtQyAfTg(UXVUa1It^ZZK=);ztiRV!jaBXa0y@TAv zV5m~dTfLs+!=QC^Y;ZU?oGl*p6q3+@tnB6t)DLT)sNQcMCg0UQ+#Hqr%AkKIWwhc1{d zAu#3Ag=7^Ri$^)w{}@AnMu%9vMN(QX_A2QRkL~1w%XEW0m1HY0HcRFmfoOzFv{Q(6 z@>Lc=bZlz9A>Vbp$BG}ge?qrJ?fc8AUKOYX(To|}KxONiINpeZg2&ykZ(?HgbTZ=j z*G13BlKcA}4z*1QZ!oZ+>YuZ_ur>8YfeKEaUCrun5B3hsGhqRdy$&|Vn%j)khQO1h zBQv<&Qz`||Z?xhfqc}I%IU71$EMp=WoE$WFeIv}&R1y2%Y7~RAW~#pQ-u_R<@3d*{SnF;4Ou{6CQ<5le`q=%;Te*2+J(kx#yjV-@AX`K7y0TE~)pkg`i!P7Qr)w_7BcZV~O>pXA+-AdkUafnMT8 zK6w$*2&|0gzCNh5ceQ|re z5k*v*^Wh4w3;^|vVwaa_pfai#1kLTcCutPW#BSQ!@4_~LkLBOQdJ%Db{Z77N{j&ds zyS~RCDiX#AtPGU5=vkqHDvBjsp5?OBhuXAI)fQQ@UO3C2@p0)@!D<17f>A{?1W=LF zv2)quKj41y#)=^pvgU0`Lr*t*hKxOU#?u(Uv}<_y`6UJ_68Y@}0~Y(Y8}Gw|fV0Y! z3R5l$l$q{{e6%*>rVKNHPp#ZiC101v8_zb+Tf_lCG!u)3ajUl1e*LGv>HIgY2W9sj z*9p>~oJk&G&O4(B1XHPnlJe0vIjugR6^<%eau|=Q1-70m_{s%(P)>)*8wAB4N?i+4 zW=E*%Z9U74A;Fh9@j5)xvY`$bvrwD1oW}lYY0m^Aw4&-p@+;Un->unDM%1iWHEkop zx?RV{ujcgTDJax?mwIGnm!P>>pHvMaf>%gI-4C>Tz4nh!cc;wNAJP1xTF0%+RV&$d zVhw5@H)OryVIkoE`?YGwv8Z4;p8SVZ`^}*bP*~=@lr1yrMbO?y_#uCtqn^dndg&8b zNHt~bOQifFAd6kr`+nG{@qAUa%2mBy*}#g;-gP9f<9tr!wOnNv?GfM}1Oz@8;HM6>067?#nIIIZEil!k=1uSzl8MipB`Z}@nVYbi1Pd_po99d`gxA| z0~nM$4A`Lv87@J_J^ED=XsBUepCKyw?nkBss2Cy!X!o7pjGFrPNYGfn;r)tV85Y4w z;OiW}Elxf!ccdX$dEU-D5DGHr_3I^Sy6<8|BHB?<()^88qa+-Hr^-g9-&(Vi&#EnQ zFw4z+7Ajw*;?uhjnuw>?G^RDy{$eh-h+v5nU7H1oQ zB51=3v_uAFYB>8y$JGO~oWTROZN?jbb9Pb}@O#p{%9E!1$X zHRYXj;|Be;O6c{gNO-X5nIjAkiWI5hY}nEruI$AFl#8+Y_^g9Xcnx_liEZZf+of#C zhr1Q6T}33`th1tgV@kbFN)MQq*id@q68q9~+7c}J*%h3HIHklYU?yaw3B)=!4=U4) zAKW4trd$W53Dk}|ko*jiCBCvwUWhf^v(7ns1u{`Qhq>f{av9l|z+3#`Z}Rj{&JdIK zdzDS``5_y*2D8>~5XDRt$N0!&KJrsK=xvZdxMj*-pk>H66I_{{QmK|TEVlrGi|s@W zi}VY$xTd1);?0oin*|wgB(f=I{^>y55XuAZuk%rrSh`9q4Z5j!L|*D zEJl=DT2!%fV;L^Vm5>RGy6?$Y5{pC%sFQs_J<*H-UdG>R1-`aTR@xx)?YxCJG4@*| zv9D{D?(SVMXLMU0Jqk%2#0QAJ}$M^ilBcV{XZx&=q%=!7e*+1AN z=7th+QdZK*6lJ?-Ct^=*lD_q^B}v6_c$$fbff%Mo{JCr08`zo@RS0|iw6nA>D{}?aGk2xrC&(|qe4XJ@6$0C?VvSS=#p6P(J{DxUw!}8bsyu`lr^ZautH|ZIXHZWSZ++ORuP0he zd7Sh*Y}5GYz1&z7<;S~I$j`~1Zi-k0ef-tTNt_OOo z$!`$Kn2n@Ac9jiFYT~$@F`t>VU(EITMd!URxch2R-iaVF+E^Ax&=Y*Y2pk(g7@Yom7isY^qB$HWTu)U(y%H<1lj=4+uI%p(X;VV2WG8)C+lJ4D+<_}OC#7N> zOxp!Qw~$7Q9wm9+7fTYr43Vgd4#;N<#nMankK_^bt;uz!VjP(tGnkAc3n{d`2G-{ViKC!|T}) zsw|sEZAV55Cj(yGj61F|@QsQe(Zb%&2&<~cX?BtNqh4#)F@Kt`3*%;>v!CD|nRsM6 z*Ehnu=RM-W32@U5K`dh9yZN^>tGBFMkDhx={IN;0%A3=zvi=NQ%C<=!+(3;=`Ya(2crE~Aj=>9l7cw?)MT1#>5 z?V|_{DlS=*Bl$vA0Eh9DqvyoBA=-z0IP^aWCrAIjqvVI5G2oI_dHL=3ra&pD>Q|Z6 z$m3qE^b&AOtSbGU-l~Miw$)9tWDaBr)5Gz$3c5)=@5Pt^s0?w}{7n_m=6WH^9w&}F z`EomJKa9M#ZPhf9IuxJ5UU+hh49S4JiJLuS2CMG*9&OAGHoepEgGb9<52%3>P9pr* zGz_?i^|a#T#ZT-$mx+_KD$h~e>5}0Sydr(Zl#saL4{{~F_8~lNjDMKiANR({3d!EC zyM^JkTFAX{WL6x)`Yf=@xA&%lyzUMs4wqTPZ%h>dPMT!*4?CzcE!ST_H~OrucZCLJ zP$;1?^e*qCN!Bk}G|8H`j?bD*%C)J9t4w!WrW!JH?cpZfY2$sC1*%`m%odcamRH-5 zm;H&b8Xs6IrKI13nPD*iLO{L0>Ju`U8Q(lw40*0RBo21C`u1l@C*Ux*M2 zU|IlrIjlI8D)YF&aZ*L+8^PAwKun6M4ssw$G7$pb47GW{?6- zm|if|X(AFTq%HnqIdZNhj?{xrR!nWr&c2}6>b_(g=M~4yOwA0n4IqaYPyWHPB|B0u z8&=Mr9_xX-CgJdztg`EVT)HNguje7}P)3kSh{u$4H~i5*^AO6BT=zxeWVD*Z+8-eb zlQ=jA-JubN|IXHNDt~XG>U35j2@(`RYb~(Xr7Rkc#Vh zV)JC(z%SE4SwF(UA=c>Pz;Ar*0fp)S&QY0O*g=nF95td(cOCr%^r)oq?&Dljk4*~x0=r$=7Mqyd3KD7_UJA6qBrCiMHoepJ zW>h78pkiF+uiOk_SyKYB6?2OHi3^30FPo$5t z@jV+73$rSsncqY~3s3$$CAhv_b2|RC^H7WW)x`mUPY!SlVun)TzgP)9vH4e^ja0*; zR@*n<*8?I#2^9ZB@XX|7q%8dO-3zmqc4(cFAEr1H!3PRA=T$4brdpTmz)bWz-CHDV zcVyQjM;uyL10GUrXe1rF`G}xdI#Z!8;2{xJW6YqcyYn!=T=1Tv-zY@CC8+T)xVv+( zs?HzLW$iggc2eB{f7qGP2q(Iogmh5a*$=Z(CSjX2pxc?>H$-CMVx%{p)O9}4avT3S zSyyqvO5n#=VT-%zPRE)>0p5Y%LL=YBz_5EaLcZF#_*8q@81u@j)clY#rzxZ4bWa+b zrgM47eH`p%ZyzP3|Cunuc)GDp?8O!Jfs3zT{b3dxhv&N^a+G1%bz)2 z$Rd>G{y~(#Zv<50mkQTQs{Lo@T!RW2)>2{Q6wb@2o#Sm-(dy#O9-1lC4u>`)v)Ci( zC51XjD|;bA06WVg6mD54QhV`u@LGYa*zs7g6cx>F*%ucwQT3-WEpTitCKR z_{l0X-<7gxKPqiA2p>%2In=d`l)YML_VX*)22jB-GNW~3^zp#u8xG{_3F3`svSP>r zv%;)DF)!V#shEvdlxtr_A>|`QjFmai33+TD>`+qlhgWdCljzqXR^Ys9C43Gvn1bOVJsI((`@1pP81u z!Ei;&T&{FfFq2o6P(n;J@6-Gt<#m#uKy}5AscDTf$-cN8Qq2arO?SNGqv!xRa{f8+b3}6hxr5h1dG-j=PmJ}&-T#7oPp-OYJOIYIny5x^0x2lM zO&nmg@>mh;1;pr^S%$y{a?>4VX0KG!_A8b{hkY6eB@CI+c*aHk06b@gw(3#@3-Lrg za%UFmGDofJa$QLshQ4lQKgC?`=S};3?jyEt?aw0iKJ!4S#ch`#_3XUR!V@u-4ZVIq z3L?La5uP11Jp+59=nfxi)#>1u2G@rrQQYzFdgdhS$s9%fe8d?PP#IV>O>gynCuJ0c zSTO6>EwMOffAA!`v|<7YBI(z8=HB5vE&P6;U1V7=lAIj#7uP6tK`4MDg(9~8;Z4AT z&lsmCcSa23#!0{BS{|1{OZ=xn5m?0nxb*d8df$HQY%Q%iH#h^Tyq%Gl80DO;g%pU5 z)3rZ=ZcASWyYMLSpf@G2?{Ap7j?r0I$m3+p^>j#{bGTzlEN^X|a^-}yUSy(C%!+Bw z7_V(R>{vQ0Mt(qMzC>n_XrAH3Qspu@_%bdTkrNC_MM5`y0{l;qgKu6tbQkn%&Hp#v{^f?CTHT$ZZ!kySIR+pj@4 zDQFHV|EgS~UM7d4hre&5bXNN|LeQ|3kD4rD2ZwY|9Y!6v%9u_WVf8h~y@b;j;U`P< zqFep^-B&q{i-y(RFd}_$XDc=$7D@Bvp|>SNAGzv|Pt7=+30aQ<9f1j**+N;yu^H$H3p)+^+uD=kz6yx1tW^gQqw?dI^q z7j@{qU91~?pK6_NtFUJI>I;;0gmI3|GEBNG+Eic|WYpjvk+Ya{?b^bv%>hu8r>0&) z;oAj2K;X|1vGJyK=5eG+k(5aGJZ7G$?&?twT{CmKqg~HyZaEHX zrhD8iPZ3GZP23MAGDb%LY|5F5Qjc5f1EGEeo~w^@i@#s7RZ+!KG6U;-Owk7m*$kI$ zbyCQw!=m&%%Ekmq!R^%RMA8bVKIVxKl`0&c2 z8^%4s5Zpu)!i{<>hzLB3MRfH3{=J@9a6Y*B(^CfOW3R{+coADrT9>{YF2-0Xkdjgb zWtkw;;Wv*+;{I3WdfC&46!BhTdStJ+Oxi&7p$4bZQuvi(vREn zJY~fKheDfOVnu~k$?ZP!xBP5zyZ(u$ zPv&7D^(;FOg92MzzJpOtzI_Dtdo${k^?zfBZRiOz6`QY>tA81X);O_jStb*%!naSc z%T{&4(p$VFaCRU(k{kIA0=XvuL3aHH-`PjR&r~3rvI#T9zc7EmQnjm=eTF`9+URK8 zuNzK9nWuX;;d6?B4AAWQBC6~pFsz32HQIF2gc^iy(aOu(j9B|v6fJZ0QSPqrJg8LV z9n2*gfSCB_$HX0I z2=Kg{&8uO12kk0Nm+R-WuQh#X$o$l3C&-Sl-iF95Xko z5i&X(-F_tZDdYl;2BycKq0EqqJ%D-shSNLa&U-RDzED3+`aPXH@=C-j<<)5jPwq*V zP-Wn*EcPIk83&`DTK&&ENLStUeB?Gd50d0K5laAus%vBeaLhX(z^()0 zY#VlwTS4)tp*-3Q)`u%Ie>SnXF6>CUSb-HEc%+7FE^?^Te7W_gUYj6O*wYyTqOjfa%!dqi_h1 z6R9#>dv3$Es>zK`3JECG^XzB1MVFy^XDzfJkJ%AniuoCMF zylKWW(JHDdmH1aRLXKFt3J>{J7Yb@rNPE zpaG5!xe)n`5@5@yrCzx}_GL4fD@$+1Db+=h&>9+uyAEtF?j&Lnc{nuZGzw?fF;*Di zYrofX@ZOWEsuy35;TGL;NUk>ipKx#r`%JsMIu#9+{ffTu4A~{7BGQB|2~4Mw~Eosu=gfOusaA3+o(P=oQLGB*u96l z&}&T7?bgyeKPI26^QRtMyyHxJ%Zk-JT8FvQZE1tuaV4x!r|bjAQW@|m9}R0pVruXY z370E0O;^hk z2IEqxiPNgnub(||Q6HR<^jn_bQ;na!G0gbRV6ljFgWu*^E*3ONU_iLuq<>&C{}+al$_jZ+dP9|WAxKH5%=Go3_;|j?L5Z?b;KJ$C-q5v(!?koZ^r~1@ ziiNVCjLEJvWr)%W7yc$>Z42-9$4sizlZYEcmKfdbZoledTDk+HG)#=?M$Bp;5^* zsFExjXCx>;8Ebge!oj4V>#tlqM4|e|euI5C!!`&FSf4ROOF4TkBZ#Hu|CSlO`yunX zTZk&eVD64LnU&2>4es;gqjnnsuKrL=;p8PX$|qg?FHAkJ6+&H*BEZdNhT;}z3)Zxb zm@kImOe=r)WwnGRqL&s$_(;pv`<*SZm-5%k1vm@C~J@yOmd}z zldl+g&X~W1+1Ik#I7#nip0#;=y#}FZj>Dhg(i!NkjR436H$NkHF(n&uNHsZ#87q}Jv~ga zddwJ-l>ThsQ|s60ZU$<=G)vQLymDw@p`2|R0IXlh8k;;X>_&N>L?j4p9Z#w5)uf8} zM`r>x9`#l_Y>!y=p1(H8Vbae&ks%TzOnh=&^d}qryYaHDUyxPvC9j$-$xtDU{6H?j z1edU{LJDkv694T%oV~dmWt8Pq-BrTwC0djTFg8hSY^A(sQDU9SR=)?PiI7UCM@O_2 zprN_^2|p9D9(tpi?yaq4xT}7}_{ywdz7#w!7Yr`81oN5kqNG!syIQ&LZYchF^quu! zk1d|bdh~1n^LMYblVGo zd|)ydz|-~Qrk!Lfqj12l3o@L#dQIx3;`3XS;t<2I|~pjVncbAxU{5w(6;t zr5W@Gux)oFQx7=lwWEZGCQ2me)d=(wsd{5)(tV zxP9-ypYBGZeX_7Aq=lTJHajX)hUgm*s=JT_@XSv~V2|BX1+26lHeNbtA<;|R>!sYX z;k?OcE7zDwED70cv5ni4KP4YY6VAGQ+LQr%jcTXV>)C@tVjxy#C1CC%Wz}-%o>^g! z65St->n^)1#{qb#Ia}Rxm~qWtHobDQ7X*6H;Fa|amps7I0&wcKIQDR;t+E~Ln&srE zz%;p%0a{(jtKW`;8b4cNX<%EDZ8zi{(c$Vs0|ZV+I=(B0+t+g@L;943j*Coyo9jR$ zC>T&o-W12)YB`(QowVjT(Qy;_IV5s`B${qh*x>yxHA+D=ZfZu-jjeC{h5kJjF}_Pr z1b>TXZKg47*iF4G@cp&0zoMZMB5rqaGKg_NC}dZen!8%&1YO^1XwjIpTafmzY%1gw zK~14@g~h6J92ceKe{N^Q1RC8V4`QzRVbu4ybPL|y9?z`OU;S1VcrFS-$1RJ%YrnWU z)Scy_Ke#|BNn@_|34F^osTVL9U}JpTh!FJ`r6nQ~G5|%hc-_2G@7%e#%02{!RHIpu zaPtsk?u5kP|6XkNs{_lVRivB?ozMt1R_0(wHEjd%n3vyTtu!-ShNU%C|m**zlttH_1NWvbt~v^eehRaIrb5-$PmbxbPs*;X&gcF0j}Bo^3*liz>Kd% zC|+e>9K&{^XB1%Erw&+8hvUUe=cblS z!gIoImVf0@c7t4N78c(?IgQPrtvH2~ZPrd>S1xAJH55VLSi{R5f##ZiHp0+t2VP&;??17ld{MN
>W>1*l+Q5uIrPK4fFze^o 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%0AOq`9N$qBO%Vg2ys0+Ye= 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

d9z{)&`^oi!OWC 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 z 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%0DdM#t6Fr^^jR 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

`0(gs7WLs2elsr`07Cuy@HS} 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

<__zvy@8nK%yr)oiHN1{LqQZgxq4GQcr@e}kO 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

    ?=*qH8BxYnIL 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 Date: Fri, 19 Apr 2024 15:02:17 +1000 Subject: [PATCH 0374/1116] Updated make file --- Makefile.nitro | 6 ++++++ scripts/aws/Dockerfile | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile.nitro b/Makefile.nitro index 0fb257bc4..14dbd717d 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -66,6 +66,12 @@ build/proxies.nitro.yaml: build_artifacts ./scripts/aws/proxies.nitro.yaml build/syslog-ng-client.conf: build_artifacts ./scripts/aws/syslog-ng/syslog-ng-client.conf cp ./scripts/aws/syslog-ng/syslog-ng-client.conf ./build/ +build/syslog-ng-core_4.6.0-1_amd64.deb: build_artifacts ./scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb + cp ./scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb ./build/ + +build/syslog-ng-ose-pub.asc: build_artifacts ./scripts/aws/syslog-ng/client/syslog-ng-ose-pub.asc + cp ./scripts/aws/syslog-ng/client/syslog-ng-ose-pub.asc ./build/ + build/entrypoint.sh: build_artifacts cp ./scripts/aws/entrypoint.sh ./build/ diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 2508d9c9f..359547e66 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -14,8 +14,8 @@ ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} ENV ENCLAVE_ENVIRONMENT="aws-nitro" ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" -COPY ./syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ -COPY ./syslog-ng/client/syslog-ng-ose-pub.asc /app/dep/ +COPY ./syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ +COPY ./syslog-ng-ose-pub.asc /app/dep/ RUN apt update -y \ && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ @@ -39,8 +39,9 @@ COPY ./conf/integ-uid2-config.json /app/conf/ COPY ./conf/prod-euid-config.json /app/conf/ COPY ./conf/integ-euid-config.json /app/conf/ COPY ./conf/*.xml /app/conf/ -COPY ./syslog-ng/syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf +COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh + CMD ["/app/entrypoint.sh"] From 10ce439b1e3a387e47a4c766a71cae34f35eee50 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 19 Apr 2024 05:04:15 +0000 Subject: [PATCH 0375/1116] [CI Pipeline] Released Snapshot version: 5.28.144-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6988d8cb1..52d051cc1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.139-SNAPSHOT + 5.28.144-SNAPSHOT UTF-8 From d35841f32af1de9e9e37f42c9a84b755a48b4913 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 19 Apr 2024 15:14:50 +1000 Subject: [PATCH 0376/1116] Updated make file --- Makefile.nitro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.nitro b/Makefile.nitro index 14dbd717d..395685024 100644 --- a/Makefile.nitro +++ b/Makefile.nitro @@ -13,11 +13,11 @@ all: build_eif build_eif: uid2operator.eif euidoperator.eif -uid2operator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py +uid2operator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/syslog-ng-core_4.6.0-1_amd64.deb build/syslog-ng-ose-pub.asc build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./uid2operator.tar uid2operator; docker cp ./uid2operator.tar amazonlinux:/uid2operator.tar docker exec amazonlinux bash aws_nitro_eif.sh uid2operator -euidoperator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py +euidoperator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/syslog-ng-core_4.6.0-1_amd64.deb build/syslog-ng-ose-pub.asc build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./euidoperator.tar euidoperator; docker cp ./euidoperator.tar amazonlinux:/euidoperator.tar docker exec amazonlinux bash aws_nitro_eif.sh euidoperator From f4a047414a88ef32f8de07799ffe39236f16fec8 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 19 Apr 2024 05:17:14 +0000 Subject: [PATCH 0377/1116] [CI Pipeline] Released Snapshot version: 5.28.146-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 52d051cc1..05126b619 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.144-SNAPSHOT + 5.28.146-SNAPSHOT UTF-8 From 4bda88fe31cc08d441965ee26bcb40a2a6351b9a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 21 Apr 2024 12:53:26 -0600 Subject: [PATCH 0378/1116] updated shared version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6479932d3..4ab336143 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.3.0-0c9c5b24fe + 7.8.0-35dfded760 ${project.version} From fc08b7fdbfe5ed85116c89b8a41aedcf10b7d9be Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 21 Apr 2024 12:58:44 -0600 Subject: [PATCH 0379/1116] update aws java sdk version to latest for vulnerability --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ab336143..6df03ec06 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ com.amazonaws aws-java-sdk-s3 - 1.12.368 + 1.12.705 com.iabtcf From cbb40be444f9c2ec39a8c148260da16cf07a6a37 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 21 Apr 2024 20:25:12 +0000 Subject: [PATCH 0380/1116] [CI Pipeline] Released Snapshot version: 5.28.101-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 650853903..35d77d152 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.89-53761606d2 + 5.28.101-SNAPSHOT UTF-8 From 54f1a2276bb84330403c878021f9e0b2d28a6e0c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 21 Apr 2024 20:35:53 +0000 Subject: [PATCH 0381/1116] [CI Pipeline] Released Snapshot version: 5.28.102-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35d77d152..324e0a0be 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.101-SNAPSHOT + 5.28.102-SNAPSHOT UTF-8 From dd1cd817be36e805b9710c5121c186ddb83c2db8 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 21 Apr 2024 20:57:20 +0000 Subject: [PATCH 0382/1116] [CI Pipeline] Released Snapshot version: 5.28.103-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 324e0a0be..57ca1d4fc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.102-SNAPSHOT + 5.28.103-SNAPSHOT UTF-8 From c71fc92b0465f8cd551a8e05b973b0c964ad15e2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 21 Apr 2024 21:32:44 +0000 Subject: [PATCH 0383/1116] [CI Pipeline] Released Snapshot version: 5.28.104-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 57ca1d4fc..a10c85fbd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.103-SNAPSHOT + 5.28.104-SNAPSHOT UTF-8 From 09c88f3a8274b33003f3ad7a6ca892bbaa45f7bb Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sun, 21 Apr 2024 17:41:40 -0600 Subject: [PATCH 0384/1116] capitalization fix --- src/main/java/com/uid2/operator/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index 3cc8a6e65..9c485ed5d 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -173,7 +173,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception { System.exit(1); } if (saltProvider.getSnapshot(Instant.now()).getExpires().isBefore(Instant.now())) { - LOGGER.error("All salts are expired"); + LOGGER.error("all salts are expired"); System.exit(1); } } From 91ca87b9291b70d127607c22c273a0fdb447784d Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 22 Apr 2024 02:38:06 +0000 Subject: [PATCH 0385/1116] [CI Pipeline] Released Patch version: 5.28.148-348b21fcf8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 05126b619..c537bef9c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.146-SNAPSHOT + 5.28.148-348b21fcf8 UTF-8 From 6352b73c48b533170c34264dc21e43ef4f26b08e Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 22 Apr 2024 12:46:42 +1000 Subject: [PATCH 0386/1116] Set the reference to main branch --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index dc7d2fba2..cbd9e559c 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,7 +115,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -129,7 +129,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-2984-test-syslog-ng + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 0e19e2cb92bdca994f032b04beddb3ea14bd281c Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 22 Apr 2024 11:56:44 +1000 Subject: [PATCH 0387/1116] CSTG: Validate app name - App name is sent as part of the request payload. - App name is part of the AAD. - App name check is case insensitive. - Invalid app names are logged together with invalid origins. - App name check is controlled by the existing feature flag `client_side_token_generate_domain_name_check_enabled`. --- pom.xml | 2 +- .../com/uid2/operator/model/CstgRequest.java | 7 ++ .../TokenResponseStatsCollector.java | 1 + .../uid2/operator/service/ResponseUtil.java | 1 + .../operator/vertx/UIDOperatorVerticle.java | 105 ++++++++++++++---- .../com.uid2.core/test/sites/sites.json | 3 +- .../operator/ExtendedUIDOperatorVerticle.java | 2 +- .../operator/UIDOperatorVerticleTest.java | 92 +++++++++++++-- 8 files changed, 182 insertions(+), 31 deletions(-) diff --git a/pom.xml b/pom.xml index 91dd2a03d..06b9b9568 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.3.0-0c9c5b24fe + 7.7.6-1e644a0ded-SNAPSHOT ${project.version} diff --git a/src/main/java/com/uid2/operator/model/CstgRequest.java b/src/main/java/com/uid2/operator/model/CstgRequest.java index 81a618e96..8294e9fc5 100644 --- a/src/main/java/com/uid2/operator/model/CstgRequest.java +++ b/src/main/java/com/uid2/operator/model/CstgRequest.java @@ -11,6 +11,9 @@ public class CstgRequest { private String publicKey; private long timestamp; + @JsonProperty("app_name") + private String appName; + public String getPayload() { return payload; } @@ -30,5 +33,9 @@ public String getPublicKey() { public long getTimestamp() { return timestamp; } + + public String getAppName() { + return appName; + } } diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index b565786f9..e32920512 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -31,6 +31,7 @@ public enum ResponseStatus { BadPublicKey, BadSubscriptionId, InvalidHttpOrigin, + InvalidAppName, BadIV, BadPayload, //the actual cstg payload in the JSON request BadJsonPayload, // can't even deserialise the JSON payload diff --git a/src/main/java/com/uid2/operator/service/ResponseUtil.java b/src/main/java/com/uid2/operator/service/ResponseUtil.java index a515d1f34..aa9040b22 100644 --- a/src/main/java/com/uid2/operator/service/ResponseUtil.java +++ b/src/main/java/com/uid2/operator/service/ResponseUtil.java @@ -175,5 +175,6 @@ public static class ResponseStatus { public static final String UnknownError = "unknown"; public static final String InsufficientUserConsent = "insufficient_user_consent"; public static final String InvalidHttpOrigin = "invalid_http_origin"; + public static final String InvalidAppName = "invalid_app_name"; } } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index e9c59af56..393c5ed95 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -115,7 +115,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final int allowClockSkewSeconds; protected int maxSharingLifetimeSeconds; protected boolean keySharingEndpointProvideSiteDomainNames; - protected Map> siteIdToInvalidOrigins = new HashMap<>(); + protected Map> siteIdToInvalidOriginsAndAppNames = new HashMap<>(); protected Instant lastInvalidOriginProcessTime = Instant.now(); public UIDOperatorVerticle(JsonObject config, @@ -299,6 +299,14 @@ private Set getDomainNameListForClientSideTokenGenerate(ClientSideKeypai } } + private Set getAppNames(ClientSideKeypair keypair) { + final Site site = siteProvider.getSite(keypair.getSiteId()); + if (site == null) { + return Collections.emptySet(); + } + return site.getAppNames(); + } + private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchAlgorithmException, InvalidKeyException { final JsonObject body; try { @@ -324,18 +332,8 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA return; } - if (cstgDoDomainNameCheck) { - final Set domainNames = getDomainNameListForClientSideTokenGenerate(clientSideKeypair); - String origin = rc.request().getHeader("origin"); - - boolean allowedDomain = DomainNameCheckUtil.isDomainNameAllowed(origin, domainNames); - if (!allowedDomain) { - if (clientSideTokenGenerateLogInvalidHttpOrigin) { - handleInvalidHttpOriginError(clientSideKeypair.getSiteId(), origin); - } - SendClientErrorResponseAndRecordStats(ResponseStatus.InvalidHttpOrigin, 403, rc, "unexpected http origin", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, siteProvider); - return; - } + if (!hasValidOriginOrAppName(rc, request, clientSideKeypair)) { + return; } if (request.getPayload() == null || request.getIv() == null || request.getPublicKey() == null) { @@ -375,14 +373,17 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA return; } - final byte[] aad = new JsonArray(List.of(request.getTimestamp())).toBuffer().getBytes(); + final JsonArray aad = JsonArray.of(request.getTimestamp()); + if (request.getAppName() != null) { + aad.add(request.getAppName()); + } final byte[] requestPayloadBytes; try { final byte[] encryptedPayloadBytes = Base64.getDecoder().decode(request.getPayload()); final byte[] ivAndCiphertext = Arrays.copyOf(ivBytes, 12 + encryptedPayloadBytes.length); System.arraycopy(encryptedPayloadBytes, 0, ivAndCiphertext, 12, encryptedPayloadBytes.length); - requestPayloadBytes = decrypt(ivAndCiphertext, 0, sharedSecret, aad); + requestPayloadBytes = decrypt(ivAndCiphertext, 0, sharedSecret, aad.toBuffer().getBytes()); } catch (Exception e) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "payload decryption failed", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); return; @@ -465,6 +466,69 @@ else if(emailHash != null) { recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityTokens.getAdvertisingTokenVersion()); } + private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair) { + final OriginOrAppNameValidationResult validationResult = validateOriginOrAppName(rc, request, keypair); + if (validationResult.isSuccess) { + return true; + } + + if (clientSideTokenGenerateLogInvalidHttpOrigin) { + logInvalidOriginOrAppName(keypair.getSiteId(), validationResult.originOrAppName); + } + SendClientErrorResponseAndRecordStats(validationResult.errorStatus, 403, rc, validationResult.message, keypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, validationResult.responseStatus, siteProvider); + return false; + } + + private OriginOrAppNameValidationResult validateOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair) { + if (!cstgDoDomainNameCheck) { + return OriginOrAppNameValidationResult.SUCCESS; + } + + final String appName = request.getAppName(); + if (appName != null) { + return getAppNames(keypair).stream().anyMatch(appName::equalsIgnoreCase) + ? OriginOrAppNameValidationResult.SUCCESS + : OriginOrAppNameValidationResult.invalidAppName(appName); + } + + final String origin = rc.request().getHeader("origin"); + final Set domainNames = getDomainNameListForClientSideTokenGenerate(keypair); + + return origin != null && DomainNameCheckUtil.isDomainNameAllowed(origin, domainNames) + ? OriginOrAppNameValidationResult.SUCCESS + : OriginOrAppNameValidationResult.invalidHttpOrigin(origin); + } + + private static class OriginOrAppNameValidationResult { + private final boolean isSuccess; + + private final String errorStatus; + + private final String message; + + private final TokenResponseStatsCollector.ResponseStatus responseStatus; + + private final String originOrAppName; + + public static final OriginOrAppNameValidationResult SUCCESS = new OriginOrAppNameValidationResult(true, null, null, null, null); + + public static OriginOrAppNameValidationResult invalidAppName(String appName) { + return new OriginOrAppNameValidationResult(false, ResponseStatus.InvalidAppName, "unexpected app name", TokenResponseStatsCollector.ResponseStatus.InvalidAppName, appName); + } + + public static OriginOrAppNameValidationResult invalidHttpOrigin(String origin) { + return new OriginOrAppNameValidationResult(false, ResponseStatus.InvalidHttpOrigin, "unexpected http origin", TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, origin); + } + + private OriginOrAppNameValidationResult(boolean isSuccess, String errorStatus, String message, TokenResponseStatsCollector.ResponseStatus responseStatus, String originOrAppName) { + this.isSuccess = isSuccess; + this.errorStatus = errorStatus; + this.message = message; + this.responseStatus = responseStatus; + this.originOrAppName = originOrAppName; + } + } + private IdentityTokens generateOptedOutIdentityTokens(PrivacyBits privacyBits, InputUtil.InputVal input, ClientSideKeypair clientSideKeypair) { UserIdentity cstgOptOutIdentity; if (input.getIdentityType() == IdentityType.Email) { @@ -1858,14 +1922,15 @@ private void sendJsonResponse(RoutingContext rc, JsonArray json) { .end(json.encode()); } - private void handleInvalidHttpOriginError(int siteId, String origin) { - Set uniqueInvalidOrigins = siteIdToInvalidOrigins.computeIfAbsent(siteId, k -> new HashSet<>()); - uniqueInvalidOrigins.add(origin); + private void logInvalidOriginOrAppName(int siteId, String originOrAppName) { + siteIdToInvalidOriginsAndAppNames.computeIfAbsent(siteId, k -> new HashSet<>()) + .add(originOrAppName); if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(Duration.ofMinutes(60)) >= 0) { lastInvalidOriginProcessTime = Instant.now(); - LOGGER.error(generateInvalidHttpOriginMessage(siteIdToInvalidOrigins)); - siteIdToInvalidOrigins.clear(); + // Leaving the format of the log message unchanged for now, but logging invalid app names. + LOGGER.error(generateInvalidHttpOriginMessage(siteIdToInvalidOriginsAndAppNames)); + siteIdToInvalidOriginsAndAppNames.clear(); } } diff --git a/src/main/resources/com.uid2.core/test/sites/sites.json b/src/main/resources/com.uid2.core/test/sites/sites.json index 1f5628e74..6bb74ce18 100644 --- a/src/main/resources/com.uid2.core/test/sites/sites.json +++ b/src/main/resources/com.uid2.core/test/sites/sites.json @@ -3,7 +3,8 @@ "id": 123, "name": "MegaTest Site", "enabled": true, - "domain_names" : ["localhost", "uidapi.com"] + "domain_names" : ["localhost", "uidapi.com"], + "app_names": ["com.123.Game.App.android", "123456789", "com.123.Game.App.ios", "com.uid2.devapp"] }, { "id": 124, diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index 1793f6016..5946263b2 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -47,6 +47,6 @@ public void setLastInvalidOriginProcessTime(Instant lastInvalidOriginProcessTime } public void setSiteIdToInvalidOrigins(Map> siteIdToInvalidOrigins) { - this.siteIdToInvalidOrigins = siteIdToInvalidOrigins; + this.siteIdToInvalidOriginsAndAppNames = siteIdToInvalidOrigins; } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 5bbb03bfa..52052105d 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -2665,7 +2665,9 @@ void requestWithReferer(Vertx vertx, VertxTestContext testContext) { private void postCstg(Vertx vertx, String endpoint, String httpOriginHeader, JsonObject body, Handler>> handler) { WebClient client = WebClient.create(vertx); HttpRequest req = client.postAbs(getUrlForEndpoint(endpoint)); - req.putHeader("origin", httpOriginHeader); + if (httpOriginHeader != null) { + req.putHeader("origin", httpOriginHeader); + } req.sendJsonObject(body, handler); } @@ -2684,14 +2686,19 @@ private void sendCstg(Vertx vertx, String endpoint, String httpOriginHeader, Jso }))); } - private void setupCstgBackend(String... domainNames) + private void setupCstgBackend(String... domainNames) { + setupCstgBackend(List.of(domainNames), Collections.emptyList()); + } + + private void setupCstgBackend(List domainNames, List appNames) { setupSalts(); setupKeys(); ClientSideKeypair keypair = new ClientSideKeypair(clientSideTokenGenerateSubscriptionId, clientSideTokenGeneratePublicKey, clientSideTokenGeneratePrivateKey, clientSideTokenGenerateSiteId, "", Instant.now(), false, ""); when(clientSideKeypairProvider.getSnapshot()).thenReturn(clientSideKeypairSnapshot); when(clientSideKeypairSnapshot.getKeypair(clientSideTokenGenerateSubscriptionId)).thenReturn(keypair); - when(siteProvider.getSite(clientSideTokenGenerateSiteId)).thenReturn(new Site(clientSideTokenGenerateSiteId, "test", true, new HashSet<>(List.of(domainNames)))); + final Site site = new Site(clientSideTokenGenerateSiteId, "test", true, Collections.emptySet(), new HashSet<>(domainNames), new HashSet<>(appNames)); + when(siteProvider.getSite(clientSideTokenGenerateSiteId)).thenReturn(site); } //if no identity is provided will get an error @@ -2747,6 +2754,37 @@ void cstgDomainNameCheckFails(boolean setOptoutCheckFlagInRequest, String httpOr }); } + @ParameterizedTest + @CsvSource({ + "''", // An empty quoted value results in the empty string. + "com.123", + "com.", + }) + void cstgAppNameCheckFails(String appName, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + setupCstgBackend(Collections.emptyList(), List.of("com.123.Game.App.android")); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), false, appName); + sendCstg(vertx, + "v2/token/client-generate", + null, + data.getItem1(), + data.getItem2(), + 403, + testContext, + respJson -> { + final JsonObject expectedResponse = new JsonObject() + .put("message", "unexpected app name") + .put("status", "invalid_app_name"); + + assertEquals(expectedResponse, respJson); + + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.InvalidAppName); + testContext.completeNow(); + }); + } + @ParameterizedTest @CsvSource({ "true,http://gototest.com", @@ -2851,6 +2889,33 @@ void cstgDomainNameCheckPasses(boolean setOptoutCheckFlagInRequest, String httpO }); } + @ParameterizedTest + @CsvSource({ + "com.123.Game.App.android", + "com.123.game.app.android", + "123456789", + }) + void cstgAppNameCheckPasses(String appName, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + setupCstgBackend(Collections.emptyList(), List.of("com.123.Game.App.android", "123456789")); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), false, appName); + sendCstg(vertx, + "v2/token/client-generate", + null, + data.getItem1(), + data.getItem2(), + 200, + testContext, + respJson -> { + assertEquals("success", respJson.getString("status")); + + JsonObject refreshBody = respJson.getJsonObject("body"); + assertNotNull(refreshBody); + var encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + validateAndGetToken(encoder, refreshBody, IdentityType.Email); //to validate token version is correct + testContext.completeNow(); + }); + } + @Test void cstgNoBody(Vertx vertx, VertxTestContext testContext) { setupCstgBackend("cstg.co.uk"); @@ -3272,7 +3337,7 @@ void cstgNoPhoneSupport(Vertx vertx, VertxTestContext testContext) throws NoSuch }); } - private Tuple.Tuple2 createClientSideTokenGenerateRequestWithPayload(JsonObject identityPayload, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException { + private Tuple.Tuple2 createClientSideTokenGenerateRequestWithPayload(JsonObject identityPayload, long timestamp, String appName) throws NoSuchAlgorithmException, InvalidKeyException { final KeyFactory kf = KeyFactory.getInstance("EC"); final PublicKey serverPublicKey = ClientSideTokenGenerateTestUtil.stringToPublicKey(clientSideTokenGeneratePublicKey, kf); @@ -3280,8 +3345,11 @@ private Tuple.Tuple2 createClientSideTokenGenerateRequest final SecretKey secretKey = ClientSideTokenGenerateTestUtil.deriveKey(serverPublicKey, clientPrivateKey); final byte[] iv = Random.getBytes(12); - final byte[] aad = new JsonArray(List.of(timestamp)).toBuffer().getBytes(); - byte[] payloadBytes = ClientSideTokenGenerateTestUtil.encrypt(identityPayload.toString().getBytes(), secretKey.getEncoded(), iv, aad); + final JsonArray aad = JsonArray.of(timestamp); + if (appName != null) { + aad.add(appName); + } + byte[] payloadBytes = ClientSideTokenGenerateTestUtil.encrypt(identityPayload.toString().getBytes(), secretKey.getEncoded(), iv, aad.toBuffer().getBytes()); final String payload = EncodingUtils.toBase64String(payloadBytes); JsonObject requestJson = new JsonObject(); @@ -3291,10 +3359,18 @@ private Tuple.Tuple2 createClientSideTokenGenerateRequest requestJson.put("timestamp", timestamp); requestJson.put("subscription_id", clientSideTokenGenerateSubscriptionId); + if (appName != null) { + requestJson.put("app_name", appName); + } + return new Tuple.Tuple2<>(requestJson, secretKey); } private Tuple.Tuple2 createClientSideTokenGenerateRequest(IdentityType identityType, String rawId, long timestamp, boolean setOptoutCheckFlagInRequest) throws NoSuchAlgorithmException, InvalidKeyException { + return createClientSideTokenGenerateRequest(identityType, rawId, timestamp, setOptoutCheckFlagInRequest, null); + } + + private Tuple.Tuple2 createClientSideTokenGenerateRequest(IdentityType identityType, String rawId, long timestamp, boolean setOptoutCheckFlagInRequest, String appName) throws NoSuchAlgorithmException, InvalidKeyException { JsonObject identity = new JsonObject(); @@ -3312,12 +3388,12 @@ else if(identityType == IdentityType.Phone) { identity.put("optout_check", 1); } - return createClientSideTokenGenerateRequestWithPayload(identity, timestamp); + return createClientSideTokenGenerateRequestWithPayload(identity, timestamp, appName); } private Tuple.Tuple2 createClientSideTokenGenerateRequestWithNoPayload(long timestamp) throws NoSuchAlgorithmException, InvalidKeyException { JsonObject identity = new JsonObject(); - return createClientSideTokenGenerateRequestWithPayload(identity, timestamp); + return createClientSideTokenGenerateRequestWithPayload(identity, timestamp, null); } From 291e2095de0c0b594a24a3bae85e2b9b10f2497e Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 22 Apr 2024 02:51:06 +0000 Subject: [PATCH 0388/1116] [CI Pipeline] Released Patch version: 5.28.152-20c315dfc7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c537bef9c..47abe8ade 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.148-348b21fcf8 + 5.28.152-20c315dfc7 UTF-8 From 5b35912a63f6195ec0f00c36e97e38456b14eb05 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 22 Apr 2024 14:12:36 +1000 Subject: [PATCH 0389/1116] Use latest version for version_number --- .github/workflows/publish-all-operators.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-all-operators.yaml b/.github/workflows/publish-all-operators.yaml index 3bc13d34e..38502a24f 100644 --- a/.github/workflows/publish-all-operators.yaml +++ b/.github/workflows/publish-all-operators.yaml @@ -60,7 +60,7 @@ jobs: - name: Set version number id: version - uses: IABTechLab/uid2-shared-actions/actions/version_number@v1.0 + uses: IABTechLab/uid2-shared-actions/actions/version_number@v2 with: type: ${{ inputs.release_type }} branch_name: ${{ github.ref }} @@ -123,6 +123,11 @@ jobs: runs-on: ubuntu-latest needs: [start, buildPublic, buildGCP, buildAzure, buildAWS] steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Download public manifest uses: actions/download-artifact@v4 with: From 68467e64dd89f23f982151d1257a9bf1b231c355 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 22 Apr 2024 04:17:00 +0000 Subject: [PATCH 0390/1116] [CI Pipeline] Released Patch version: 5.28.156 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 47abe8ade..31e8c72f5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.152-20c315dfc7 + 5.28.156 UTF-8 From afcbc48bd6441fe03bf02c401f09b8844b96c355 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 22 Apr 2024 16:27:23 -0600 Subject: [PATCH 0391/1116] fix merge --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a10c85fbd..461d6ca2f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.104-SNAPSHOT + 5.28.156 UTF-8 From 7166507c7ee387d9dcdd0b58c5fbb213025c118a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 22 Apr 2024 16:30:12 -0600 Subject: [PATCH 0392/1116] fix merge --- pom.xml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 461d6ca2f..fde3dafd0 100644 --- a/pom.xml +++ b/pom.xml @@ -31,8 +31,12 @@ snapshots-repo https://s01.oss.sonatype.org/content/repositories/snapshots - false - true + + false + + + true + @@ -148,7 +152,7 @@ ch.qos.logback logback-core - 1.3.12 + 1.5.3 ch.qos.logback @@ -158,7 +162,13 @@ com.github.loki4j loki-logback-appender - 1.2.0 + 1.5.1 + + + net.logstash.logback + logstash-logback-encoder + 7.4 + runtime com.amazonaws From 1a5e7d6625ebd781ae750a7a60ba0e68536e8872 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 22 Apr 2024 16:33:01 -0600 Subject: [PATCH 0393/1116] fix merge --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fde3dafd0..b94ffa31f 100644 --- a/pom.xml +++ b/pom.xml @@ -157,7 +157,7 @@ ch.qos.logback logback-classic - 1.3.12 + 1.5.3 com.github.loki4j From 9dec531aa03a643e3562a23423c362247ea9c435 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 22 Apr 2024 22:38:00 +0000 Subject: [PATCH 0394/1116] [CI Pipeline] Released Snapshot version: 5.28.157-alpha-118-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b94ffa31f..f4fb53268 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.156 + 5.28.157-alpha-118-SNAPSHOT UTF-8 From 05be1e510097485574d0414116c9e1b821888b39 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 23 Apr 2024 09:32:39 +1000 Subject: [PATCH 0395/1116] Updated uid2-shared version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 06b9b9568..3beb5cb47 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a - 7.7.6-1e644a0ded-SNAPSHOT + 7.9.0 ${project.version} From 636a743259e880a967ea970225eddf20f5e6d6b8 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 23 Apr 2024 09:28:05 +1000 Subject: [PATCH 0396/1116] Rename methods and parameters Also update log message to start with "InvalidHttpOriginAndAppName" --- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 9 ++++----- .../com/uid2/operator/ExtendedUIDOperatorVerticle.java | 4 ++-- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 393c5ed95..df41978d1 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1928,17 +1928,16 @@ private void logInvalidOriginOrAppName(int siteId, String originOrAppName) { if (Duration.between(lastInvalidOriginProcessTime, Instant.now()).compareTo(Duration.ofMinutes(60)) >= 0) { lastInvalidOriginProcessTime = Instant.now(); - // Leaving the format of the log message unchanged for now, but logging invalid app names. - LOGGER.error(generateInvalidHttpOriginMessage(siteIdToInvalidOriginsAndAppNames)); + LOGGER.error(generateInvalidOriginAndAppNameMessage(siteIdToInvalidOriginsAndAppNames)); siteIdToInvalidOriginsAndAppNames.clear(); } } - private String generateInvalidHttpOriginMessage(Map> siteIdToInvalidOrigins) { + private String generateInvalidOriginAndAppNameMessage(Map> siteIdToInvalidOriginsAndAppNames) { StringBuilder invalidHttpOriginMessage = new StringBuilder(); - invalidHttpOriginMessage.append("InvalidHttpOrigin: "); + invalidHttpOriginMessage.append("InvalidHttpOriginAndAppName: "); boolean mapHasFirstElement = false; - for (Map.Entry> entry : siteIdToInvalidOrigins.entrySet()) { + for (Map.Entry> entry : siteIdToInvalidOriginsAndAppNames.entrySet()) { if(mapHasFirstElement) { invalidHttpOriginMessage.append(" | "); } diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index 5946263b2..0df46158c 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -46,7 +46,7 @@ public void setLastInvalidOriginProcessTime(Instant lastInvalidOriginProcessTime this.lastInvalidOriginProcessTime = lastInvalidOriginProcessTime; } - public void setSiteIdToInvalidOrigins(Map> siteIdToInvalidOrigins) { - this.siteIdToInvalidOriginsAndAppNames = siteIdToInvalidOrigins; + public void setSiteIdToInvalidOriginsAndAppNames(Map> siteIdToInvalidOriginsAndAppNames) { + this.siteIdToInvalidOriginsAndAppNames = siteIdToInvalidOriginsAndAppNames; } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 52052105d..521e8acdc 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -2809,7 +2809,7 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagI assertFalse(respJson.containsKey("body")); assertEquals("unexpected http origin", respJson.getString("message")); assertEquals("invalid_http_origin", respJson.getString("status")); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOrigin: site test (123): http://gototest.com")); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOriginAndAppName: site test (123): http://gototest.com")); assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, @@ -2833,7 +2833,7 @@ void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(boolean setOptoutChe siteIdToInvalidOrigins.put(clientSideTokenGenerateSiteId, new HashSet<>(Arrays.asList("http://localhost1.com", "http://localhost2.com"))); siteIdToInvalidOrigins.put(124, new HashSet<>(Arrays.asList("http://xyz1.com", "http://xyz2.com"))); - this.uidOperatorVerticle.setSiteIdToInvalidOrigins(siteIdToInvalidOrigins); + this.uidOperatorVerticle.setSiteIdToInvalidOriginsAndAppNames(siteIdToInvalidOrigins); setupCstgBackend(); when(siteProvider.getSite(124)).thenReturn(new Site(124, "test2", true, new HashSet<>())); @@ -2850,7 +2850,7 @@ void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(boolean setOptoutChe assertFalse(respJson.containsKey("body")); assertEquals("unexpected http origin", respJson.getString("message")); assertEquals("invalid_http_origin", respJson.getString("status")); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOrigin: site test (123): http://localhost1.com, http://gototest.com, http://localhost2.com | site test2 (124): http://xyz1.com, http://xyz2.com")); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOriginAndAppName: site test (123): http://localhost1.com, http://gototest.com, http://localhost2.com | site test2 (124): http://xyz1.com, http://xyz2.com")); assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, From e9848c1cb1ce06c3b74bfbc8ed90e97996cd56f6 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 23 Apr 2024 09:32:13 +1000 Subject: [PATCH 0397/1116] Refactor logging of invalid origins and app names --- .../operator/vertx/UIDOperatorVerticle.java | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index df41978d1..d6f844a44 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1934,29 +1934,15 @@ private void logInvalidOriginOrAppName(int siteId, String originOrAppName) { } private String generateInvalidOriginAndAppNameMessage(Map> siteIdToInvalidOriginsAndAppNames) { - StringBuilder invalidHttpOriginMessage = new StringBuilder(); - invalidHttpOriginMessage.append("InvalidHttpOriginAndAppName: "); - boolean mapHasFirstElement = false; + List logEntries = new ArrayList<>(); for (Map.Entry> entry : siteIdToInvalidOriginsAndAppNames.entrySet()) { - if(mapHasFirstElement) { - invalidHttpOriginMessage.append(" | "); - } - mapHasFirstElement = true; int siteId = entry.getKey(); Set origins = entry.getValue(); String siteName = getSiteName(siteProvider, siteId); - String site = "site " + siteName + " (" + siteId + "): "; - invalidHttpOriginMessage.append(site); - boolean setHasFirstElement = false; - for (String origin : origins) { - if(setHasFirstElement) { - invalidHttpOriginMessage.append(", "); - } - setHasFirstElement = true; - invalidHttpOriginMessage.append(origin); - } + logEntries.add("site " + siteName + " (" + siteId + "): " + String.join(", ", origins)); } - return invalidHttpOriginMessage.toString(); + return "InvalidHttpOriginAndAppName: " + + String.join(" | ", logEntries); } public enum UserConsentStatus { From 2d5140aa59696f2822b154adbefa940bd5b42c92 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 23 Apr 2024 15:12:44 +1000 Subject: [PATCH 0398/1116] Add a validation for Azure build --- .../publish-public-operator-docker-image.yaml | 1 - .github/workflows/validate-image.yaml | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index 050b75bcc..e54e91d57 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -64,7 +64,6 @@ jobs: with: release_type: ${{ inputs.release_type }} version_number_input: ${{ inputs.version_number_input }} - cloud_provider: 'default' force_release: 'no' # Do not create a release for the component builds, will be created by the parent vulnerability_severity: ${{ inputs.vulnerability_severity }} secrets: inherit diff --git a/.github/workflows/validate-image.yaml b/.github/workflows/validate-image.yaml index 9f96a0be0..855782e38 100644 --- a/.github/workflows/validate-image.yaml +++ b/.github/workflows/validate-image.yaml @@ -40,4 +40,12 @@ jobs: fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'gcp' secrets: inherit - needs: [build-publish-docker-aws] \ No newline at end of file + needs: [build-publish-docker-aws] + build-publish-docker-azure: + uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 + with: + failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} + fail_on_error: ${{ inputs.fail_on_error || true }} + cloud_provider: 'azure' + secrets: inherit + needs: [build-publish-docker-gcp] \ No newline at end of file From 0aeb9a0ee52f20778b9a8ba4dc62487227e2699e Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Tue, 23 Apr 2024 15:27:53 +1000 Subject: [PATCH 0399/1116] Add test for logging invalid app name --- .../operator/UIDOperatorVerticleTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 521e8acdc..a0bbcb569 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -2818,6 +2818,29 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagI }); } + @ParameterizedTest + @ValueSource(strings = { "badAppName" }) + void cstgLogsInvalidAppName(String appName, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); + this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); + + setupCstgBackend(); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), false, appName); + sendCstg(vertx, + "v2/token/client-generate", + null, + data.getItem1(), + data.getItem2(), + 403, + testContext, + respJson -> { + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOriginAndAppName: site test (123): " + appName)); + testContext.completeNow(); + }); + } + @ParameterizedTest @CsvSource({ "true,http://gototest.com", From 356f0e304fece81aa42a13f121cb7e517be9b234 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 23 Apr 2024 16:58:46 +1000 Subject: [PATCH 0400/1116] Update action versions to remove warnings --- .github/workflows/e2e-azure-cc-enclave.yaml | 6 +++--- .github/workflows/e2e-gcp-oidc-enclave.yaml | 6 +++--- .github/workflows/node.js.yaml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e2e-azure-cc-enclave.yaml b/.github/workflows/e2e-azure-cc-enclave.yaml index 084462e1b..f7671ff92 100644 --- a/.github/workflows/e2e-azure-cc-enclave.yaml +++ b/.github/workflows/e2e-azure-cc-enclave.yaml @@ -26,17 +26,17 @@ jobs: packages: read steps: - name: Checkout full history - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout uid2-core repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: IABTechLab/uid2-core token: ${{ secrets.GHCR_PAT }} path: core - name: Checkout uid2-optout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: IABTechLab/uid2-optout token: ${{ secrets.GHCR_PAT }} diff --git a/.github/workflows/e2e-gcp-oidc-enclave.yaml b/.github/workflows/e2e-gcp-oidc-enclave.yaml index a8479cb3c..9c415dcac 100644 --- a/.github/workflows/e2e-gcp-oidc-enclave.yaml +++ b/.github/workflows/e2e-gcp-oidc-enclave.yaml @@ -27,17 +27,17 @@ jobs: id-token: write steps: - name: Checkout full history - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout uid2-core repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: IABTechLab/uid2-core token: ${{ secrets.GHCR_PAT }} path: core - name: Checkout uid2-optout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: IABTechLab/uid2-optout token: ${{ secrets.GHCR_PAT }} diff --git a/.github/workflows/node.js.yaml b/.github/workflows/node.js.yaml index 12caafe43..e4507da05 100644 --- a/.github/workflows/node.js.yaml +++ b/.github/workflows/node.js.yaml @@ -20,9 +20,9 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' From 858465b1fa46045608ecae16d116551ec04c31bc Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 23 Apr 2024 18:53:16 +0000 Subject: [PATCH 0401/1116] [CI Pipeline] Released Minor version: 5.29.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7200d3764..d904675b4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.28.157-alpha-118-SNAPSHOT + 5.29.0 UTF-8 diff --git a/version.json b/version.json index e93c43b41..209bd3ab3 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.28", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.29", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From 2fc97f0539c08fe11b3a807b6a49ee598df1705c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 23 Apr 2024 22:12:37 +0000 Subject: [PATCH 0402/1116] [CI Pipeline] Released Patch version: 5.29.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d904675b4..b86c48498 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.29.0 + 5.29.2 UTF-8 From 883cc9b0da0311929d51f64b7f5383a5ddfd9eae Mon Sep 17 00:00:00 2001 From: Ian Nara <135270994+Ian-Nara@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:48:49 -0600 Subject: [PATCH 0403/1116] Bug Fix, Initialize Shutdown Handler For Local Run (#525) * Operator shutdown handler instantiated even if "core_attest_url" config isn't set --- src/main/java/com/uid2/operator/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index 9c485ed5d..bd58c966d 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -95,6 +95,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception { boolean useStorageMock = config.getBoolean(Const.Config.StorageMockProp, false); this.clientSideTokenGenerate = config.getBoolean(Const.Config.EnableClientSideTokenGenerate, false); this.validateServiceLinks = config.getBoolean(Const.Config.ValidateServiceLinks, false); + this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(config.getInteger(Const.Config.SaltsExpiredShutdownHours, 12)), Clock.systemUTC()); String coreAttestUrl = this.config.getString(Const.Config.CoreAttestUrlProp); @@ -103,7 +104,6 @@ public Main(Vertx vertx, JsonObject config) throws Exception { DownloadCloudStorage fsStores; if (coreAttestUrl != null) { - this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(config.getInteger(Const.Config.SaltsExpiredShutdownHours, 12)), Clock.systemUTC()); var clients = createUidClients(this.vertx, coreAttestUrl, operatorKey, this.shutdownHandler::handleAttestResponse); UidCoreClient coreClient = clients.getKey(); From 4c7bf6f4f07967cd84850c4d4c11fa96579d1c4e Mon Sep 17 00:00:00 2001 From: Gian Miguel Del Mundo Date: Wed, 24 Apr 2024 15:00:32 +0800 Subject: [PATCH 0404/1116] Removed pre-commit and trivy-secret.yaml --- .gitignore | 1 - .pre-commit-config.yaml | 17 ---- trivy-secret.yaml | 210 ---------------------------------------- 3 files changed, 228 deletions(-) delete mode 100644 .pre-commit-config.yaml delete mode 100644 trivy-secret.yaml diff --git a/.gitignore b/.gitignore index f6eafd493..1e5d984cc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,5 @@ e2e-target .DS_Store */node_modules/* *.iml -.pre-commit-trivy-cache/ # Ignore generated credentials from google-github-actions/auth gha-creds-*.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index db1c10e95..000000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,17 +0,0 @@ -repos: - - repo: https://github.com/mxab/pre-commit-trivy.git - rev: v0.5.1 - hooks: - - id: trivyfs-docker - args: - - --scanners - - secret - - --secret-config - - /src/trivy-secret.yaml - - --skip-dirs - - /src/target - - --skip-dirs - - /src/.idea - - --skip-files - - /src/e2e/docker/localstack/kms/seed.yaml - - . diff --git a/trivy-secret.yaml b/trivy-secret.yaml deleted file mode 100644 index 38eaa8ed3..000000000 --- a/trivy-secret.yaml +++ /dev/null @@ -1,210 +0,0 @@ -rules: - ################## - # UID2 Admin Key # - ################## - - id: uid2-admin-key-test - category: uid2 - title: UID2 - Admin Key - Test - severity: CRITICAL - keywords: - - UID2-A-T - regex: UID2-A-T-(?P.{6}\..{38}) - secret-group-name: secret - - id: uid2-admin-key-integ - category: uid2 - title: UID2 - Admin Key - Integ - severity: CRITICAL - keywords: - - UID2-A-I - regex: UID2-A-I-(?P.{6}\..{38}) - secret-group-name: secret - - id: uid2-admin-key-prod - category: uid2 - title: UID2 - Admin Key - Prod - severity: CRITICAL - keywords: - - UID2-A-P - regex: UID2-A-P-(?P.{6}\..{38}) - secret-group-name: secret - - ################### - # UID2 Client Key # - ################### - - id: uid2-client-key-test - category: uid2 - title: UID2 - Client Key - Test - severity: CRITICAL - keywords: - - UID2-C-T - regex: UID2-C-T-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: uid2-client-key-integ - category: uid2 - title: UID2 - Client Key - Integ - severity: CRITICAL - keywords: - - UID2-C-I - regex: UID2-C-I-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: uid2-client-key-prod - category: uid2 - title: UID2 - Client Key - Prod - severity: CRITICAL - keywords: - - UID2-C-P - regex: UID2-C-P-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - ##################### - # UID2 Operator Key # - ##################### - - id: uid2-operator-key-test - category: uid2 - title: UID2 - Operator Key - Test - severity: CRITICAL - keywords: - - UID2-O-T - regex: UID2-O-T-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: uid2-operator-key-integ - category: uid2 - title: UID2 - Operator Key - Integ - severity: CRITICAL - keywords: - - UID2-O-I - regex: UID2-O-I-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: uid2-operator-key-prod - category: uid2 - title: UID2 - Operator Key - Prod - severity: CRITICAL - keywords: - - UID2-O-P - regex: UID2-O-P-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - ######################################## - # UID2 Client Side Keypair Private Key # - ######################################## - - id: uid2-client-side-keypair-private-key-test - category: uid2 - title: UID2 - Client Side Keypair Private Key - Test - severity: CRITICAL - keywords: - - UID2-Y-T - regex: (?PUID2-Y-T-.{92}) - secret-group-name: secret - - id: uid2-client-side-keypair-private-key-integ - category: uid2 - title: UID2 - Client Side Keypair Private Key - Integ - severity: CRITICAL - keywords: - - UID2-Y-I - regex: (?PUID2-Y-I-.{92}) - secret-group-name: secret - - id: uid2-client-side-keypair-private-key-prod - category: uid2 - title: UID2 - Client Side Keypair Private Key - Prod - severity: CRITICAL - keywords: - - UID2-Y-P - regex: (?PUID2-Y-P-.{92}) - secret-group-name: secret - - ################## - # EUID Admin Key # - ################## - - id: euid-admin-key-test - category: euid - title: EUID - Admin Key - Test - severity: CRITICAL - keywords: - - EUID-A-T - regex: EUID-A-T-(?P.{6}\..{38}) - secret-group-name: secret - - id: euid-admin-key-integ - category: euid - title: EUID - Admin Key - Integ - severity: CRITICAL - keywords: - - EUID-A-I - regex: EUID-A-I-(?P.{6}\..{38}) - secret-group-name: secret - - id: euid-admin-key-prod - category: euid - title: EUID - Admin Key - Prod - severity: CRITICAL - keywords: - - EUID-A-P - regex: EUID-A-P-(?P.{6}\..{38}) - secret-group-name: secret - - ################### - # EUID Client Key # - ################### - - id: euid-client-key-test - category: euid - title: EUID - Client Key - Test - severity: CRITICAL - keywords: - - EUID-C-T - regex: EUID-C-T-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: euid-client-key-integ - category: euid - title: EUID - Client Key - Integ - severity: CRITICAL - keywords: - - EUID-C-I - regex: EUID-C-I-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: euid-client-key-prod - category: euid - title: EUID - Client Key - Prod - severity: CRITICAL - keywords: - - EUID-C-P - regex: EUID-C-P-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - ##################### - # EUID Operator Key # - ##################### - - id: euid-operator-key-test - category: euid - title: EUID - Operator Key - Test - severity: CRITICAL - keywords: - - EUID-O-T - regex: EUID-O-T-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: euid-operator-key-integ - category: euid - title: EUID - Operator Key - Integ - severity: CRITICAL - keywords: - - EUID-O-I - regex: EUID-O-I-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - - id: euid-operator-key-prod - category: euid - title: EUID - Operator Key - Prod - severity: CRITICAL - keywords: - - EUID-O-P - regex: EUID-O-P-[0-9]+-(?P.{6}\..{38}) - secret-group-name: secret - -disable-allow-rules: - - tests - - examples - - vendor - - usr-dirs - - locale-dir - - markdown - - node.js - - golang - - python - - rubygems - - wordpress - - anaconda-log From 83b39fb4eb0429fa950eb699aee53c352f9c9321 Mon Sep 17 00:00:00 2001 From: Asloob Qureshi Date: Wed, 24 Apr 2024 10:09:39 -0700 Subject: [PATCH 0405/1116] [UID2-2831] Send Site's app name in key/sharing and key/bidstream endpoints (#508) * Send app names in sharing and bidstream endpoints * Return app names list in key sharing and bidstream calls * Removed flag for sending site domains * simplify code and use case sensitive names * Update tests with minor changes * Update test * simplified test code * remove unnecessary null checks --- conf/local-config.json | 2 +- conf/local-e2e-docker-public-config.json | 2 +- conf/local-e2e-public-config.json | 2 +- ...dator-latest-e2e-docker-public-config.json | 2 +- .../operator/vertx/UIDOperatorVerticle.java | 39 +++-- .../test/keyset_keys/keyset_keys.json | 8 + .../com.uid2.core/test/keysets/keysets.json | 9 ++ .../com.uid2.core/test/sites/sites.json | 7 + .../operator/ExtendedUIDOperatorVerticle.java | 4 +- .../operator/UIDOperatorVerticleTest.java | 142 ++++++++++++------ 10 files changed, 155 insertions(+), 62 deletions(-) diff --git a/conf/local-config.json b/conf/local-config.json index eca081f74..59332c650 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -34,7 +34,7 @@ "optout_partition_interval": 86400, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, - "key_sharing_endpoint_provide_site_domain_names": true, + "key_sharing_endpoint_provide_app_names": true, "client_side_token_generate_log_invalid_http_origins": true, "salts_expired_shutdown_hours": 12 } diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index 8190951fe..af29da6f7 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -24,7 +24,7 @@ "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, "client_side_token_generate_log_invalid_http_origins": true, - "key_sharing_endpoint_provide_site_domain_names": true, + "key_sharing_endpoint_provide_app_names": true, "validate_service_links": true, "optout_s3_bucket": "test-optout-bucket", "optout_s3_folder": "optout-v2/", diff --git a/conf/local-e2e-public-config.json b/conf/local-e2e-public-config.json index e8ba64930..d36dc9139 100644 --- a/conf/local-e2e-public-config.json +++ b/conf/local-e2e-public-config.json @@ -37,7 +37,7 @@ "optout_partition_interval": 86400, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, - "key_sharing_endpoint_provide_site_domain_names": true, + "key_sharing_endpoint_provide_app_names": true, "client_side_token_generate_log_invalid_http_origins": true, "salts_expired_shutdown_hours": 12 } diff --git a/conf/validator-latest-e2e-docker-public-config.json b/conf/validator-latest-e2e-docker-public-config.json index 2b94970d2..d6789bd00 100644 --- a/conf/validator-latest-e2e-docker-public-config.json +++ b/conf/validator-latest-e2e-docker-public-config.json @@ -25,7 +25,7 @@ "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, "client_side_token_generate_log_invalid_http_origins": true, - "key_sharing_endpoint_provide_site_domain_names": true, + "key_sharing_endpoint_provide_app_names": true, "validate_service_links": true, "optout_s3_bucket": "test-optout-bucket", "optout_s3_folder": "optout-v2/", diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index e1af48cc7..8f2e20012 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -50,6 +50,7 @@ import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.handler.CorsHandler; import io.vertx.ext.web.handler.StaticHandler; +import org.apache.commons.collections4.CollectionUtils; import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -115,8 +116,8 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final int maxBidstreamLifetimeSeconds; private final int allowClockSkewSeconds; protected int maxSharingLifetimeSeconds; - protected boolean keySharingEndpointProvideSiteDomainNames; protected Map> siteIdToInvalidOriginsAndAppNames = new HashMap<>(); + protected boolean keySharingEndpointProvideAppNames; protected Instant lastInvalidOriginProcessTime = Instant.now(); public UIDOperatorVerticle(JsonObject config, @@ -153,7 +154,7 @@ public UIDOperatorVerticle(JsonObject config, this.phoneSupport = config.getBoolean("enable_phone_support", true); this.tcfVendorId = config.getInteger("tcf_vendor_id", 21); this.cstgDoDomainNameCheck = config.getBoolean("client_side_token_generate_domain_name_check_enabled", true); - this.keySharingEndpointProvideSiteDomainNames = config.getBoolean("key_sharing_endpoint_provide_site_domain_names", false); + this.keySharingEndpointProvideAppNames = config.getBoolean("key_sharing_endpoint_provide_app_names", false); this._statsCollectorQueue = statsCollectorQueue; this.clientKeyProvider = clientKeyProvider; this.clientSideTokenGenerateLogInvalidHttpOrigin = config.getBoolean("client_side_token_generate_log_invalid_http_origins", false); @@ -670,7 +671,7 @@ private void addBidstreamHeaderFields(JsonObject resp) { } private void addSites(JsonObject resp, List keys, Map keysetMap) { - final List sites = getSitesWithDomainNames(keys, keysetMap); + final List sites = getSitesWithDomainOrAppNames(keys, keysetMap); if (sites != null) { /* The end result will look something like this: @@ -686,14 +687,16 @@ private void addSites(JsonObject resp, List keys, Map sitesJson = sites.stream() - .map(UIDOperatorVerticle::toJson) + .map(site -> UIDOperatorVerticle.toJson(site, keySharingEndpointProvideAppNames)) .collect(Collectors.toList()); resp.put("site_data", sitesJson); } @@ -732,12 +735,9 @@ private void addAllowClockSkewSecondsField(JsonObject resp) { resp.put("allow_clock_skew_seconds", allowClockSkewSeconds); } - private List getSitesWithDomainNames(List keys, Map keysetMap) { + private List getSitesWithDomainOrAppNames(List keys, Map keysetMap) { //without cstg enabled, operator won't have site data and siteProvider could be null - //and adding keySharingEndpointProvideSiteDomainNames in case something goes wrong - //and we can still enable cstg feature but turn off site domain name download in - // key/sharing endpoint - if (!keySharingEndpointProvideSiteDomainNames || !clientSideTokenGenerate) { + if (!clientSideTokenGenerate) { return null; } @@ -747,7 +747,13 @@ private List getSitesWithDomainNames(List keys, Map !site.getDomainNames().isEmpty()) + .filter(site -> { + if (CollectionUtils.isNotEmpty(site.getDomainNames())) { + return true; + } else { + return keySharingEndpointProvideAppNames && CollectionUtils.isNotEmpty(site.getAppNames()); + } + }) .collect(Collectors.toList()); } @@ -755,10 +761,15 @@ private List getSitesWithDomainNames(List keys, Map domainOrAppNames = new HashSet<>(site.getDomainNames()); + + if (includeAppNames) { + domainOrAppNames.addAll(site.getAppNames()); + } + siteObj.put("domain_names", domainOrAppNames.stream().sorted().collect(Collectors.toList())); return siteObj; } diff --git a/src/main/resources/com.uid2.core/test/keyset_keys/keyset_keys.json b/src/main/resources/com.uid2.core/test/keyset_keys/keyset_keys.json index 21262c02c..22b869045 100644 --- a/src/main/resources/com.uid2.core/test/keyset_keys/keyset_keys.json +++ b/src/main/resources/com.uid2.core/test/keyset_keys/keyset_keys.json @@ -78,5 +78,13 @@ "created": 1609459200, "activates": 1609469200, "expires": 4088629662 + }, + { + "id": 11, + "keyset_id": 901, + "secret": "YgyxOX4yX1gYhCINq7O9XxM6jX+etXqSXluZxjB1aG1=", + "created": 1713225363, + "activates": 1713250563, + "expires": 1715756163 } ] diff --git a/src/main/resources/com.uid2.core/test/keysets/keysets.json b/src/main/resources/com.uid2.core/test/keysets/keysets.json index e47eda1e2..9c177732a 100644 --- a/src/main/resources/com.uid2.core/test/keysets/keysets.json +++ b/src/main/resources/com.uid2.core/test/keysets/keysets.json @@ -136,5 +136,14 @@ "keyset_id": 801, "name": "My keyset #5", "site_id": 8 + }, + { + "site_id": 127, + "name": "App Name Test Site Key Set 1", + "keyset_id": 901, + "default": true, + "created": 1713225363, + "enabled": true, + "allowed_sites": [123] } ] diff --git a/src/main/resources/com.uid2.core/test/sites/sites.json b/src/main/resources/com.uid2.core/test/sites/sites.json index 6bb74ce18..6ece32a0e 100644 --- a/src/main/resources/com.uid2.core/test/sites/sites.json +++ b/src/main/resources/com.uid2.core/test/sites/sites.json @@ -20,5 +20,12 @@ "id": 126, "name": "AWS Venice", "enabled": true + }, + { + "id": 127, + "name": "App Name Test Site", + "enabled": true, + "app_names" : ["com.UID2.operator.TEST", "13456789"], + "domain_names" : ["example.com", "unifiedid.com"] } ] \ No newline at end of file diff --git a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java index d30c421bd..c90259fba 100644 --- a/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java +++ b/src/test/java/com/uid2/operator/ExtendedUIDOperatorVerticle.java @@ -36,8 +36,8 @@ public IUIDOperatorService getIdService() { return this.idService; } - public void setKeySharingEndpointProvideSiteDomainNames(boolean enable) { - this.keySharingEndpointProvideSiteDomainNames = enable; + public void setKeySharingEndpointProvideAppNames(boolean enable) { + this.keySharingEndpointProvideAppNames = enable; } public void setMaxSharingLifetimeSeconds(int maxSharingLifetimeSeconds) { diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index fffbbae62..1a57827d8 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -42,6 +42,7 @@ import io.vertx.ext.web.client.WebClient; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; +import org.apache.commons.collections4.CollectionUtils; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -154,7 +155,7 @@ private void setupConfig(JsonObject config) { config.put("advertising_token_v4_percentage", getTokenVersion() == TokenVersion.V4 ? 100 : 0); config.put("identity_v3", useIdentityV3()); config.put("client_side_token_generate", true); - config.put("key_sharing_endpoint_provide_site_domain_names", true); + config.put("key_sharing_endpoint_provide_app_names", true); config.put("client_side_token_generate_log_invalid_http_origins", true); config.put(Const.Config.AllowClockSkewSecondsProp, 3600); @@ -4313,13 +4314,23 @@ void keySharingKeysets_CorrectFiltering(Vertx vertx, VertxTestContext testContex }); } + private static Site defaultMockSite(int siteId, boolean includeDomainNames, boolean includeAppNames) { + Site site = new Site(siteId, "site" + siteId, true); + if (includeDomainNames) { + site.setDomainNames(Set.of(siteId + ".com", siteId + ".co.uk")); + } + if (includeAppNames) { + site.setAppNames(Set.of(siteId + ".com.UID2.operator", siteId + "bundle123", "12345789")); + } + return site; + } + //set some default domain names for all possible sites for each unit test first - private void setupSiteDomainNameMock(int... siteIds) { + private void setupSiteDomainAndAppNameMock(boolean includeDomainNames, boolean includeAppNames, int... siteIds) { Map sites = new HashMap<>(); for(int siteId : siteIds) { - Site site = new Site(siteId, "site"+siteId, true, new HashSet<>(Arrays.asList(siteId+".com", siteId+".co.uk"))); - sites.put(site.getId(), site); + sites.put(siteId, defaultMockSite(siteId, includeDomainNames, includeAppNames)); } when(siteProvider.getAllSites()).thenReturn(new HashSet<>(sites.values())); @@ -4329,25 +4340,42 @@ private void setupSiteDomainNameMock(int... siteIds) { }); } - public HashMap> setupExpectation(int... siteIds) + private void setupMockSites(Map sites) { + when(siteProvider.getAllSites()).thenReturn(new HashSet<>(sites.values())); + when(siteProvider.getSite(anyInt())).thenAnswer(invocation -> { + int siteId = invocation.getArgument(0); + return sites.get(siteId); + }); + } + + static Map setupExpectation(boolean includeDomainNames, boolean includeAppNames, int... siteIds) { - HashMap> expectedSites = new HashMap(); + Map expectedSites = new HashMap<>(); for (int siteId : siteIds) { - List siteDomains = Arrays.asList(siteId+".co.uk", siteId+".com"); - expectedSites.put(siteId, siteDomains); + if (includeDomainNames || includeAppNames) { + expectedSites.put(siteId, defaultMockSite(siteId, includeDomainNames, includeAppNames)); + } } return expectedSites; } - public void verifyExpectedSiteDetail(HashMap> expectedSites, JsonArray actualResult) { - assertEquals(actualResult.size(), expectedSites.size()); + public void verifyExpectedSiteDetail(Map expectedSites, JsonArray actualResult) { + + assertEquals(expectedSites.size(), actualResult.size()); for(int i = 0; i < actualResult.size(); i++) { JsonObject siteDetail = actualResult.getJsonObject(i); int siteId = siteDetail.getInteger("id"); - assertTrue(expectedSites.get(siteId).containsAll((Collection) siteDetail.getMap().get("domain_names"))); + List actualDomainList = (List) siteDetail.getMap().get("domain_names"); + Site expectedSite = expectedSites.get(siteId); + int size = 0; + assertTrue(actualDomainList.containsAll(expectedSite.getDomainNames())); + size += expectedSite.getDomainNames().size(); + assertTrue(actualDomainList.containsAll(expectedSite.getAppNames())); + size += expectedSite.getAppNames().size(); + assertEquals(size, actualDomainList.size()); } } @@ -4382,13 +4410,40 @@ public void keyBidstreamReturnsCustomMaxBidstreamLifetimeHeader(Vertx vertx, Ver } } + + private static Stream testKeyDownloadEndpointKeysetsData_IDREADER() { + int[] expectedSiteIds = new int [] {101, 102}; + int[] allMockedSiteIds = new int [] {101, 102, 103, 105}; + Map expectedSitesDomainsOnly = setupExpectation(true, false, expectedSiteIds); + Map mockSitesWithDomainsOnly = setupExpectation(true, false, allMockedSiteIds); + + Map expectedSitesWithBoth = setupExpectation(true, true, expectedSiteIds); + Map mockSitesWithBoth = setupExpectation(true, true, allMockedSiteIds); + + Map expectedSitesWithAppNamesOnly = setupExpectation(false, true, expectedSiteIds); + Map mockSitesWithAppNamesOnly = setupExpectation(false, true, allMockedSiteIds); + Map emptySites = new HashMap<>(); + return Stream.of( + // Both domains and app names should be present in response + Arguments.of("true", KeyDownloadEndpoint.SHARING, mockSitesWithBoth, expectedSitesWithBoth), + Arguments.of("true", KeyDownloadEndpoint.BIDSTREAM, mockSitesWithBoth, expectedSitesWithBoth), + + // only domains should be present in response + Arguments.of("false", KeyDownloadEndpoint.SHARING, mockSitesWithDomainsOnly, expectedSitesDomainsOnly), + Arguments.of("false", KeyDownloadEndpoint.BIDSTREAM, mockSitesWithDomainsOnly, expectedSitesDomainsOnly), + + // only app names should be present in response + Arguments.of("true", KeyDownloadEndpoint.SHARING, mockSitesWithAppNamesOnly, expectedSitesWithAppNamesOnly), + Arguments.of("true", KeyDownloadEndpoint.BIDSTREAM, mockSitesWithAppNamesOnly, expectedSitesWithAppNamesOnly), + + // None + Arguments.of("false", KeyDownloadEndpoint.SHARING, emptySites, emptySites), + Arguments.of("false", KeyDownloadEndpoint.BIDSTREAM, emptySites, emptySites) + ); + } + @ParameterizedTest - @CsvSource({ - "true, SHARING", - "false, SHARING", - "true, BIDSTREAM", - "false, BIDSTREAM", - }) + @MethodSource("testKeyDownloadEndpointKeysetsData_IDREADER") // Test the /key/sharing and /key/bidstream endpoints when called with the ID_READER role. // // Tests: @@ -4398,10 +4453,11 @@ public void keyBidstreamReturnsCustomMaxBidstreamLifetimeHeader(Vertx vertx, Ver // ID_READER has no access to a keyset that is disabled - direct reject // ID_READER has no access to a keyset with an empty allowed_sites - reject by sharing // ID_READER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keyDownloadEndpointKeysets_IDREADER(boolean provideSiteDomainNames, KeyDownloadEndpoint endpoint, Vertx vertx, VertxTestContext testContext) { - - if (!provideSiteDomainNames) { - this.uidOperatorVerticle.setKeySharingEndpointProvideSiteDomainNames(false); + void keyDownloadEndpointKeysets_IDREADER(boolean provideAppNames, KeyDownloadEndpoint endpoint, + Map mockSites, Map expectedSites, + Vertx vertx, VertxTestContext testContext) { + if (!provideAppNames) { + this.uidOperatorVerticle.setKeySharingEndpointProvideAppNames(false); } String apiVersion = "v2"; int clientSiteId = 101; @@ -4435,7 +4491,7 @@ void keyDownloadEndpointKeysets_IDREADER(boolean provideSiteDomainNames, KeyDown createKey(1024, now.minusSeconds(5), now.minusSeconds(2), 9) }; - setupSiteDomainNameMock(101, 102, 103, 105); + setupMockSites(mockSites); //site 104 domain name list will be returned but we will set a blank list for it doReturn(new Site(104, "site104", true, new HashSet<>())).when(siteProvider).getSite(104); @@ -4450,16 +4506,9 @@ void keyDownloadEndpointKeysets_IDREADER(boolean provideSiteDomainNames, KeyDown checkEncryptionKeys(respJson, endpoint, clientSiteId, expectedKeys); - if(provideSiteDomainNames) { - HashMap> expectedSites = setupExpectation(101, 102); - // site 104 has empty domain name list intentionally previously so while site 104 should be included in - // this /key/sharing response, it won't appear in this domain name list - verifyExpectedSiteDetail(expectedSites, body.getJsonArray("site_data")); - } - else { - //otherwise we shouldn't even have a 'sites' field - assertNull(body.getJsonArray("site_data")); - } + // site 104 has empty domain name list intentionally previously so while site 104 should be included in + // this /key/sharing response, it won't appear in this domain name list + verifyExpectedSiteDetail(expectedSites, body.getJsonArray("site_data")); testContext.completeNow(); }); } @@ -4467,12 +4516,18 @@ void keyDownloadEndpointKeysets_IDREADER(boolean provideSiteDomainNames, KeyDown @Test void keySharingKeysets_SHARER_CustomMaxSharingLifetimeSeconds(Vertx vertx, VertxTestContext testContext) { this.uidOperatorVerticle.setMaxSharingLifetimeSeconds(999999); - keySharingKeysets_SHARER(vertx, testContext, 999999); + keySharingKeysets_SHARER(true, true, vertx, testContext, 999999); } - @Test - void keySharingKeysets_SHARER_defaultMaxSharingLifetimeSeconds(Vertx vertx, VertxTestContext testContext) { - keySharingKeysets_SHARER(vertx, testContext, this.config.getInteger(Const.Config.SharingTokenExpiryProp)); + @ParameterizedTest + @CsvSource({ + "true, true", + "true, false", + "false, false", + "true, false" + }) + void keySharingKeysets_SHARER_defaultMaxSharingLifetimeSeconds(boolean provideSiteDomainNames, boolean provideAppNames, Vertx vertx, VertxTestContext testContext) { + keySharingKeysets_SHARER(provideSiteDomainNames, provideAppNames, vertx, testContext, this.config.getInteger(Const.Config.SharingTokenExpiryProp)); } // Tests: @@ -4482,13 +4537,16 @@ void keySharingKeysets_SHARER_defaultMaxSharingLifetimeSeconds(Vertx vertx, Vert // SHARER has no access to a keyset with a missing allowed_sites - reject by sharing // SHARER has no access to a keyset with an empty allowed_sites - reject by sharing // SHARER has no access to a keyset with an allowed_sites for other sites - reject by sharing - void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int expectedMaxSharingLifetimeSeconds) { + void keySharingKeysets_SHARER(boolean provideSiteDomainNames, boolean provideAppNames, Vertx vertx, VertxTestContext testContext, int expectedMaxSharingLifetimeSeconds) { + if (!provideAppNames) { + this.uidOperatorVerticle.setKeySharingEndpointProvideAppNames(false); + } String apiVersion = "v2"; int clientSiteId = 101; fakeAuth(clientSiteId, Role.SHARER); MultipleKeysetsTests test = new MultipleKeysetsTests(); //To read these tests, open the MultipleKeysetsTests() constructor in another window so you can see the keyset contents and validate against expectedKeys - setupSiteDomainNameMock(101, 102, 103, 104, 105); + setupSiteDomainAndAppNameMock(provideSiteDomainNames, provideAppNames, 101, 102, 103, 104, 105); //Keys from these keysets are not expected: keyset6 (disabled keyset), keyset7 (sharing with ID_READERs but not SHARERs), keyset8 (not sharing with 101), keyset10 (not sharing with anyone) KeysetKey[] expectedKeys = { createKey(1001, now.minusSeconds(5), now.plusSeconds(3600), MasterKeysetId), @@ -4524,7 +4582,7 @@ void keySharingKeysets_SHARER(Vertx vertx, VertxTestContext testContext, int exp checkEncryptionKeys(respJson, KeyDownloadEndpoint.SHARING, clientSiteId, expectedKeys); - HashMap> expectedSites = setupExpectation(101, 104); + Map expectedSites = setupExpectation(provideSiteDomainNames, provideAppNames, 101, 104); verifyExpectedSiteDetail(expectedSites, respJson.getJsonObject("body").getJsonArray("site_data")); testContext.completeNow(); @@ -4545,7 +4603,7 @@ void keySharingKeysets_ReturnsMasterAndSite(Vertx vertx, VertxTestContext testCo new KeysetKey(102, "site key".getBytes(), now, now, now.plusSeconds(10), 10), }; MultipleKeysetsTests test = new MultipleKeysetsTests(Arrays.asList(keysets), Arrays.asList(encryptionKeys)); - setupSiteDomainNameMock(101, 102, 103, 104, 105); + setupSiteDomainAndAppNameMock(true, false, 101, 102, 103, 104, 105); Arrays.sort(encryptionKeys, Comparator.comparing(KeysetKey::getId)); send(apiVersion, vertx, apiVersion + "/key/sharing", true, null, null, 200, respJson -> { System.out.println(respJson); @@ -4578,7 +4636,7 @@ void keySharingKeysets_CorrectIDS(String testRun, Vertx vertx, VertxTestContext new KeysetKey(4, "key4".getBytes(), now, now, now.plusSeconds(10), 7), }; MultipleKeysetsTests test = new MultipleKeysetsTests(Arrays.asList(keysets), Arrays.asList(encryptionKeys)); - setupSiteDomainNameMock(10, 11, 12, 13); + setupSiteDomainAndAppNameMock(true, false, 10, 11, 12, 13); switch (testRun) { case "NoKeyset": siteId = 8; @@ -4620,7 +4678,7 @@ void keySharingKeysets_CorrectIDS(String testRun, Vertx vertx, VertxTestContext case "SharedKey": assertEquals(6, respJson.getJsonObject("body").getInteger("default_keyset_id")); //key 4 returned which has keyset id 7 which in turns has site id 13 - HashMap> expectedSites = setupExpectation(13); + Map expectedSites = setupExpectation(true, false,13); verifyExpectedSiteDetail(expectedSites, siteData); break; } From d92a4568e003476d026377c0ad700ae1669d35e5 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 24 Apr 2024 17:21:11 +0000 Subject: [PATCH 0406/1116] [CI Pipeline] Released Minor version: 5.30.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b86c48498..58308d85b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.29.2 + 5.30.0 UTF-8 diff --git a/version.json b/version.json index 209bd3ab3..77fd1907a 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.29", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.30", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From b626cc4ebe1fa270ef2b69cae3ad142825d75cab Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 1 May 2024 14:41:09 -0600 Subject: [PATCH 0407/1116] enable tls 1.3 --- src/main/java/com/uid2/operator/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index bd58c966d..fada75bb9 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -389,7 +389,7 @@ private static Vertx createVertx() { final int portOffset = Utils.getPortOffset(); VertxPrometheusOptions prometheusOptions = new VertxPrometheusOptions() .setStartEmbeddedServer(true) - .setEmbeddedServerOptions(new HttpServerOptions().setPort(Const.Port.PrometheusPortForOperator + portOffset)) + .setEmbeddedServerOptions(new HttpServerOptions().setPort(Const.Port.PrometheusPortForOperator + portOffset).addEnabledSecureTransportProtocol("TLSv1.3")) .setEnabled(true); MicrometerMetricsOptions metricOptions = new MicrometerMetricsOptions() From 932b47b52afdaa1f94b1901dbf8dc13226cda7e2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 1 May 2024 20:56:42 +0000 Subject: [PATCH 0408/1116] [CI Pipeline] Released Minor version: 5.31.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 58308d85b..011c74616 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.30.0 + 5.31.0 UTF-8 diff --git a/version.json b/version.json index 77fd1907a..1a95f2d6e 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.30", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.31", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From 7f9d7ebfbeaf51727c71a020ed937bd69bc9fb70 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 1 May 2024 15:40:06 -0600 Subject: [PATCH 0409/1116] enable tls 1.3 --- src/main/java/com/uid2/operator/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index fada75bb9..bd58c966d 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -389,7 +389,7 @@ private static Vertx createVertx() { final int portOffset = Utils.getPortOffset(); VertxPrometheusOptions prometheusOptions = new VertxPrometheusOptions() .setStartEmbeddedServer(true) - .setEmbeddedServerOptions(new HttpServerOptions().setPort(Const.Port.PrometheusPortForOperator + portOffset).addEnabledSecureTransportProtocol("TLSv1.3")) + .setEmbeddedServerOptions(new HttpServerOptions().setPort(Const.Port.PrometheusPortForOperator + portOffset)) .setEnabled(true); MicrometerMetricsOptions metricOptions = new MicrometerMetricsOptions() From 8738a0f74e8b0a3344b6d531fbebc26f32b40701 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 1 May 2024 15:45:12 -0600 Subject: [PATCH 0410/1116] enable tls 1.3 --- src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 8f2e20012..178c5064b 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -40,6 +40,7 @@ import io.vertx.core.Promise; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpHeaders; +import io.vertx.core.http.HttpServerOptions; import io.vertx.core.http.HttpServerResponse; import io.vertx.core.json.DecodeException; import io.vertx.core.json.JsonArray; @@ -184,7 +185,7 @@ public void start(Promise startPromise) throws Exception { final Router router = createRoutesSetup(); final int port = Const.Port.ServicePortForOperator + Utils.getPortOffset(); - vertx.createHttpServer() + vertx.createHttpServer(new HttpServerOptions().addEnabledSecureTransportProtocol("TLSv1.3")) .requestHandler(router) .listen(port, result -> { if (result.succeeded()) { From 2b5817946178965fc61479fdcdbcfff267ee3e3a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 1 May 2024 22:00:24 +0000 Subject: [PATCH 0411/1116] [CI Pipeline] Released Minor version: 5.32.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 011c74616..64f160aaa 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.31.0 + 5.32.0 UTF-8 diff --git a/version.json b/version.json index 1a95f2d6e..8eaf5b013 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.31", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.32", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From fa3c0e5c520855af492d638841ef1e862bb12ec6 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 6 May 2024 11:51:43 +1000 Subject: [PATCH 0412/1116] Add a delay on the start of the container --- scripts/azure-cc/entrypoint.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index 3fd88bbce..efcca4051 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -2,6 +2,22 @@ # # This script must be compatible with Ash (provided in eclipse-temurin Docker image) and Bash +function wait_for_sidecar() { + url="http://169.254.169.254/ping" + delay=1 + + while true; do + if curl -s --connect-timeout 5 "$url" > /dev/null; then + echo "side car started" + break + else + echo "side car not started. Retrying in $delay seconds..." + sleep $delay + delay=$((delay + 1)) + fi + done +} + TMP_FINAL_CONFIG="/tmp/final-config.tmp" if [ -z "${VAULT_NAME}" ]; then @@ -52,6 +68,9 @@ fi cat $FINAL_CONFIG +# delay the start of the operator until the side car has started correctly +wait_for_sidecar + # -- start operator echo "-- starting java application" java \ From e4fecab1d4fb17db467718bf94ff46692d01b967 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 6 May 2024 01:55:31 +0000 Subject: [PATCH 0413/1116] [CI Pipeline] Released Snapshot version: 5.32.1-alpha-105-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 64f160aaa..4db4d5716 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.0 + 5.32.1-alpha-105-SNAPSHOT UTF-8 From 91da9ae405ec17c34300221d0ea0817a7898c006 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 6 May 2024 12:13:22 +1000 Subject: [PATCH 0414/1116] Change to wget --- scripts/azure-cc/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index efcca4051..3fadc84e2 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -7,7 +7,7 @@ function wait_for_sidecar() { delay=1 while true; do - if curl -s --connect-timeout 5 "$url" > /dev/null; then + if wget -q --spider --tries=1 --timeout 5 "$url" > /dev/null; then echo "side car started" break else From ea4d0421b5fdfae8f4079afc0df1d932089401db Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 6 May 2024 02:16:27 +0000 Subject: [PATCH 0415/1116] [CI Pipeline] Released Snapshot version: 5.32.2-alpha-106-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4db4d5716..43a56544b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.1-alpha-105-SNAPSHOT + 5.32.2-alpha-106-SNAPSHOT UTF-8 From bf407c733b3334a116d019aa5271576d5fb1ef27 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 6 May 2024 15:30:12 +1000 Subject: [PATCH 0416/1116] Added a max number of retries --- scripts/azure-cc/entrypoint.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index 3fadc84e2..cddfa6c47 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -5,6 +5,7 @@ function wait_for_sidecar() { url="http://169.254.169.254/ping" delay=1 + max_retries=15 while true; do if wget -q --spider --tries=1 --timeout 5 "$url" > /dev/null; then @@ -14,6 +15,10 @@ function wait_for_sidecar() { echo "side car not started. Retrying in $delay seconds..." sleep $delay delay=$((delay + 1)) + if [ $delay -gt $max_retries ]; then + echo "side car failed to start" + break + fi fi done } From 501c99ba575f6f8c9ee9ce2a8833971ab656348b Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 6 May 2024 12:20:11 -0600 Subject: [PATCH 0417/1116] revert tls enable --- src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 178c5064b..8f2e20012 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -40,7 +40,6 @@ import io.vertx.core.Promise; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpHeaders; -import io.vertx.core.http.HttpServerOptions; import io.vertx.core.http.HttpServerResponse; import io.vertx.core.json.DecodeException; import io.vertx.core.json.JsonArray; @@ -185,7 +184,7 @@ public void start(Promise startPromise) throws Exception { final Router router = createRoutesSetup(); final int port = Const.Port.ServicePortForOperator + Utils.getPortOffset(); - vertx.createHttpServer(new HttpServerOptions().addEnabledSecureTransportProtocol("TLSv1.3")) + vertx.createHttpServer() .requestHandler(router) .listen(port, result -> { if (result.succeeded()) { From 3400e238c4132a14f018f24e501ac9ea1f9a780b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 6 May 2024 18:34:59 +0000 Subject: [PATCH 0418/1116] [CI Pipeline] Released Patch version: 5.32.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 64f160aaa..19042922d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.0 + 5.32.4 UTF-8 From 382e39affe79f625dc627910758a5171764cbe04 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 7 May 2024 09:20:41 +1000 Subject: [PATCH 0419/1116] Moved the increment to after the first attempt --- scripts/azure-cc/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/azure-cc/entrypoint.sh b/scripts/azure-cc/entrypoint.sh index cddfa6c47..14875c9bf 100644 --- a/scripts/azure-cc/entrypoint.sh +++ b/scripts/azure-cc/entrypoint.sh @@ -14,11 +14,11 @@ function wait_for_sidecar() { else echo "side car not started. Retrying in $delay seconds..." sleep $delay - delay=$((delay + 1)) if [ $delay -gt $max_retries ]; then echo "side car failed to start" break fi + delay=$((delay + 1)) fi done } From 4aa61226906704fa476d63c7d2cac59ee21d499a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 7 May 2024 00:53:42 +0000 Subject: [PATCH 0420/1116] [CI Pipeline] Released Patch version: 5.32.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 19042922d..afe4b6570 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.4 + 5.32.10 UTF-8 From 99cd7a3a7f810ae2af4a916f1fa1599a0205d879 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 7 May 2024 03:10:02 +0000 Subject: [PATCH 0421/1116] [CI Pipeline] Released Patch version: 5.32.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index afe4b6570..74d5782a9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.10 + 5.32.12 UTF-8 From 1c88bdc94af2f3676d7f766fca73b2c59a9307b7 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 6 May 2024 10:11:17 +1000 Subject: [PATCH 0422/1116] Use sum instead of reduce --- .../com/uid2/operator/store/CloudSyncOptOutStore.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index a7239f65d..711f8079a 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -389,8 +389,8 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap public long size() { return Arrays.stream(this.partitions) - .map(p -> (long)p.size()) - .reduce(0L, (a, b) -> a + b); + .mapToLong(OptOutPartition::size) + .sum(); } // method provided for OptOutService to assess health @@ -655,8 +655,8 @@ private void updateIndexTimestamp(Instant ts) { private BloomFilter newBloomFilter(OptOutPartition[] newPartitions) { long newSize = Arrays.stream(newPartitions) - .map(p -> (long)p.size()) - .reduce(0L, (a, b) -> a + b); + .mapToLong(OptOutPartition::size) + .sum(); BloomFilter bf = this.bloomFilter; if (bf.capacity() < newSize || bf.load() > 0.1) { From 5205b2a43edd49dc605829d8c6342b23af5f9923 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 6 May 2024 10:15:38 +1000 Subject: [PATCH 0423/1116] Change type of OptOutStoreSnapshot.fsLocal --- .../java/com/uid2/operator/store/CloudSyncOptOutStore.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 711f8079a..480649055 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -8,6 +8,7 @@ import com.uid2.operator.service.EncodingUtils; import com.uid2.shared.Utils; import com.uid2.shared.cloud.CloudStorageException; +import com.uid2.shared.cloud.DownloadCloudStorage; import com.uid2.shared.cloud.ICloudStorage; import com.uid2.shared.cloud.MemCachedStorage; import com.uid2.shared.optout.*; @@ -325,7 +326,7 @@ public static class OptOutStoreSnapshot { private static final AtomicLong bloomFilterMax = new AtomicLong(0); private static final AtomicLong totalEntries = new AtomicLong(0); - private final ICloudStorage fsLocal; + private final DownloadCloudStorage fsLocal; // holds a heap data structure for unsorted optout entries // a new optout log will be produced at a regular interval (5mins), which will be loaded to heap @@ -344,7 +345,7 @@ public static class OptOutStoreSnapshot { private final FileUtils fileUtils; - public OptOutStoreSnapshot(ICloudStorage fsLocal, JsonObject jsonConfig) { + public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig) { this.fsLocal = fsLocal; this.fileUtils = new FileUtils(jsonConfig); From 6cb64d42d50a5f86498d171d907ede48da5e3b40 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 6 May 2024 11:33:13 +1000 Subject: [PATCH 0424/1116] Use Collections.emptySet --- src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 480649055..d5b7d267a 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -365,7 +365,7 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig) this.partitions[0] = this.heap.toPartition(true); // initially no indexed files - this.indexedFiles = Collections.unmodifiableSet(new HashSet<>()); + this.indexedFiles = Collections.emptySet(); } public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap heap, From 21df0dc0094c79c16c065fc4d1d4422aaee59826 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 6 May 2024 12:04:28 +1000 Subject: [PATCH 0425/1116] Pass Clock to OptOutStoreSnapshot for testing --- src/main/java/com/uid2/operator/Main.java | 2 +- .../uid2/operator/store/CloudSyncOptOutStore.java | 15 ++++++++++----- .../uid2/operator/benchmark/BenchmarkCommon.java | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index bd58c966d..d71222060 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -140,7 +140,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception { this.keysetProvider = new RotatingKeysetProvider(fsStores, new GlobalScope(new CloudPath(keysetMdPath))); String saltsMdPath = this.config.getString(Const.Config.SaltsMetadataPathProp); this.saltProvider = new RotatingSaltProvider(fsStores, saltsMdPath); - this.optOutStore = new CloudSyncOptOutStore(vertx, fsLocal, this.config, operatorKey); + this.optOutStore = new CloudSyncOptOutStore(vertx, fsLocal, this.config, operatorKey, Clock.systemUTC()); if (this.validateServiceLinks) { String serviceMdPath = this.config.getString(Const.Config.ServiceMetadataPathProp); diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index d5b7d267a..616854821 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -30,6 +30,7 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.time.Clock; import java.time.Instant; import java.util.*; import java.util.concurrent.atomic.AtomicLong; @@ -49,7 +50,7 @@ public class CloudSyncOptOutStore implements IOptOutStore { private final String remoteApiPath; private final String remoteApiBearerToken; - public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonConfig, String operatorKey) throws MalformedURLException { + public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonConfig, String operatorKey, Clock clock) throws MalformedURLException { this.fsLocal = fsLocal; this.webClient = WebClient.create(vertx); @@ -67,7 +68,7 @@ public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonC this.remoteApiBearerToken = null; } - this.snapshot.set(new OptOutStoreSnapshot(fsLocal, jsonConfig)); + this.snapshot.set(new OptOutStoreSnapshot(fsLocal, jsonConfig, clock)); } @Override @@ -345,7 +346,10 @@ public static class OptOutStoreSnapshot { private final FileUtils fileUtils; - public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig) { + private final Clock clock; + + public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, Clock clock) { + this.clock = clock; this.fsLocal = fsLocal; this.fileUtils = new FileUtils(jsonConfig); @@ -370,6 +374,7 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig) public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap heap, OptOutPartition[] newPartitions, IndexUpdateContext iuc) { + this.clock = last.clock; this.fsLocal = last.fsLocal; this.fileUtils = last.fileUtils; this.iteration = last.iteration + 1; @@ -422,7 +427,7 @@ public long getOptOutTimestamp(byte[] hashBytes) { } public OptOutStoreSnapshot updateIndex(Collection cachedPath) throws IOException, CloudStorageException { - IndexUpdateMessage ium = this.getIndexUpdateMessage(Instant.now(), cachedPath); + IndexUpdateMessage ium = this.getIndexUpdateMessage(clock.instant(), cachedPath); return this.updateIndex(ium); } @@ -472,7 +477,7 @@ private OptOutStoreSnapshot updateIndex(IndexUpdateMessage ium) throws IOExcepti // noop for EMPTY message if (ium.equals(IndexUpdateMessage.EMPTY)) { // empty index update message also updates last updated timestamp - this.updateIndexTimestamp(Instant.now()); + this.updateIndexTimestamp(clock.instant()); // empty message won't increase iteration counter return this; diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 38f870c6b..896190d3d 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -181,7 +181,7 @@ static class StaticOptOutStore implements IOptOutStore { private CloudSyncOptOutStore.OptOutStoreSnapshot snapshot; public StaticOptOutStore(ICloudStorage storage, JsonObject jsonConfig, Collection partitions) throws CloudStorageException, IOException { - snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(storage, jsonConfig); + snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(storage, jsonConfig, Clock.systemUTC()); snapshot = snapshot.updateIndex(partitions); System.out.println(snapshot.size()); } From b56a752b04d5f9c587ab5bf965d617338760b33d Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Fri, 3 May 2024 15:06:11 +1000 Subject: [PATCH 0426/1116] Workaround for calling toPartition on an empty heap This change is to make OptOutStoreSnapshot testable. Calling toPartition on an empty heap causes an assertion failure. One place this happens is in the constructor for OptOutStoreSnapshot, making it untestable. To work around this, we use a null OptOutPartition. --- .../uid2/operator/store/CloudSyncOptOutStore.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 616854821..073be26c0 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -366,7 +366,8 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, // initially 1 partition this.partitions = new OptOutPartition[1]; - this.partitions[0] = this.heap.toPartition(true); + // First partition intentionally null. + // Calling toPartition on an empty heap causes an assertion failure. // initially no indexed files this.indexedFiles = Collections.emptySet(); @@ -395,6 +396,7 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap public long size() { return Arrays.stream(this.partitions) + .filter(Objects::nonNull) .mapToLong(OptOutPartition::size) .sum(); } @@ -418,6 +420,7 @@ public long getOptOutTimestamp(byte[] hashBytes) { } for (OptOutPartition s : this.partitions) { + if (s == null) continue; long ts = s.getOptOutTimestamp(hashBytes); if (ts != -1) return ts; } @@ -557,7 +560,8 @@ private OptOutStoreSnapshot processDeltas(IndexUpdateContext iuc) { // create a copy array, and replace the 1st entry OptOutPartition[] newPartitions = Arrays.copyOf(this.partitions, this.partitions.length); - newPartitions[0] = this.heap.toPartition(true); + // Calling toPartition on an empty heap causes an assertion failure. + newPartitions[0] = this.heap.isEmpty() ? null : this.heap.toPartition(true); OptOutStoreSnapshot.bloomFilterSize.set(this.bloomFilter.size()); return new OptOutStoreSnapshot(this, this.bloomFilter, this.heap, newPartitions, iuc); @@ -579,7 +583,8 @@ private OptOutStoreSnapshot processPartitions(IndexUpdateContext iuc) { } // produce a in-mem sorted partition for entries in heap - newPartitions[0] = newHeap.toPartition(true); + // Calling toPartition on an empty heap causes an assertion failure. + newPartitions[0] = newHeap.isEmpty() ? null : newHeap.toPartition(true); // the order of partition files needs to be sorted in time descending order int snapIndex = 1; @@ -661,6 +666,7 @@ private void updateIndexTimestamp(Instant ts) { private BloomFilter newBloomFilter(OptOutPartition[] newPartitions) { long newSize = Arrays.stream(newPartitions) + .filter(Objects::nonNull) .mapToLong(OptOutPartition::size) .sum(); From 95110e3f8f2500550eef08e9f77d5a8bb5f88828 Mon Sep 17 00:00:00 2001 From: Matt Collins Date: Mon, 6 May 2024 17:08:00 +1000 Subject: [PATCH 0427/1116] Add method OptOutStoreSnapshot.getAdIdOptOutTimestamp --- .../operator/store/CloudSyncOptOutStore.java | 23 +++ .../store/OptOutStoreSnapshotTest.java | 157 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 073be26c0..fe7ee3a2d 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -35,6 +35,7 @@ import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; @@ -326,6 +327,7 @@ public static class OptOutStoreSnapshot { private static final AtomicLong bloomFilterSize = new AtomicLong(0); private static final AtomicLong bloomFilterMax = new AtomicLong(0); private static final AtomicLong totalEntries = new AtomicLong(0); + private static final BiFunction OPT_OUT_TIMESTAMP_MERGE_STRATEGY = Long::min; private final DownloadCloudStorage fsLocal; @@ -336,6 +338,12 @@ public static class OptOutStoreSnapshot { // a bloom filter to help optimizing the non-existing case for optout entry lookup private final BloomFilter bloomFilter; + + /** + * A map from advertising IDs to optout timestamps. + */ + private final Map adIdToOptOutTimestamp; + // array of optout partitions private final OptOutPartition[] partitions; @@ -364,6 +372,8 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, int heapCapacity = jsonConfig.getInteger(Const.Config.OptOutHeapDefaultCapacityProp); this.heap = new OptOutHeap(heapCapacity); + this.adIdToOptOutTimestamp = Collections.emptyMap(); + // initially 1 partition this.partitions = new OptOutPartition[1]; // First partition intentionally null. @@ -390,6 +400,15 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap newIndexedFiles.addAll(iuc.loadedPartitions.keySet()); this.indexedFiles = Collections.unmodifiableSet(newIndexedFiles); + HashMap newOptOutTimestamps = new HashMap<>(); + for (OptOutPartition partition : this.partitions) { + if (partition == null) continue; + partition.forEach(entry -> { + newOptOutTimestamps.merge(entry.advertisingIdToB64(), entry.timestamp, OPT_OUT_TIMESTAMP_MERGE_STRATEGY); + }); + } + this.adIdToOptOutTimestamp = Collections.unmodifiableMap(newOptOutTimestamps); + // update total entries totalEntries.set(size()); } @@ -407,6 +426,10 @@ public boolean isHealthy(Instant now) { return lastUpdatedTimestamp.get().plusSeconds(fileUtils.lookbackGracePeriod()).isAfter(now); } + public long getAdIdOptOutTimestamp(String advertisingId) { + return this.adIdToOptOutTimestamp.getOrDefault(advertisingId, -1L); + } + // method provided for OptOutService to call public long getOptOutTimestamp(byte[] hashBytes) { // null hash is a special case, we will return now() epoch seconds for null hash diff --git a/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java b/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java new file mode 100644 index 000000000..b27e36309 --- /dev/null +++ b/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java @@ -0,0 +1,157 @@ +package com.uid2.operator.store; + +import com.uid2.operator.Const; +import com.uid2.shared.cloud.CloudStorageException; +import com.uid2.shared.cloud.DownloadCloudStorage; +import com.uid2.shared.cloud.MemCachedStorage; +import com.uid2.shared.optout.OptOutConst; +import com.uid2.shared.optout.OptOutEntry; +import com.uid2.shared.optout.OptOutUtils; +import io.vertx.core.json.JsonObject; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.temporal.ChronoUnit; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.mockito.Mockito.mock; + +class OptOutStoreSnapshotTest { + @Nested + class GetAdIdOptOutTimestamp { + @Test + void emptySnapshotReturnsNegativeOne() { + DownloadCloudStorage fsStore = mock(DownloadCloudStorage.class); + JsonObject config = make1mOptOutEntryConfig(); + CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, Clock.systemUTC()); + assertEquals(-1L, snapshot.getAdIdOptOutTimestamp(OptOutEntry.newRandom().advertisingIdToB64())); + } + + @ParameterizedTest + @CsvSource({ + "1,1", + "10,1", + "10,10" + }) + void emptySnapshotUpdatedWithDeltaFilesReturnsCorrectTimestamps(int deltaFileCount, int entriesPerDeltaFileCount) throws CloudStorageException, IOException { + assumeTrue(deltaFileCount > 0); + assumeTrue(entriesPerDeltaFileCount > 0); + + // Arrange + Clock clock = Clock.fixed(Instant.parse("2024-05-06T10:15:30.00Z"), ZoneOffset.UTC); + + MemCachedStorage fsStore = new MemCachedStorage(); + + List entries = new ArrayList<>(); + + for (int i = 0; i < deltaFileCount; i++) { + Instant deltaFileTimestamp = clock.instant() + .minus(deltaFileCount, ChronoUnit.HOURS); + + List deltaEntries = createDelta(entriesPerDeltaFileCount, deltaFileTimestamp, fsStore); + entries.addAll(deltaEntries); + } + + Set paths = new HashSet<>(fsStore.list(OptOutUtils.prefixDeltaFile)); + + JsonObject config = make1mOptOutEntryConfig(); + + // Act + CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, clock) + .updateIndex(paths); + + // Assert + for (OptOutEntry entry : entries) { + assertEquals(entry.timestamp, snapshot.getAdIdOptOutTimestamp(entry.advertisingIdToB64())); + } + } + + @ParameterizedTest + @CsvSource({ + "1,1", + "10,1", + "10,10" + }) + void emptySnapshotUpdatedWithPartitionFilesReturnsCorrectTimestamps(int partitionFileCount, int entriesPerPartitionFileCount) throws CloudStorageException, IOException { + assumeTrue(partitionFileCount > 0); + assumeTrue(entriesPerPartitionFileCount > 0); + + // Arrange + Clock clock = Clock.fixed(Instant.parse("2024-05-06T10:15:30.00Z"), ZoneOffset.UTC); + + MemCachedStorage fsStore = new MemCachedStorage(); + + List entries = new ArrayList<>(); + + for (int i = 0; i < partitionFileCount; i++) { + Instant partitionTimestamp = clock.instant() + .minus(i, ChronoUnit.DAYS); + + List partitionEntries = createPartition(entriesPerPartitionFileCount, partitionTimestamp, fsStore); + entries.addAll(partitionEntries); + } + + Set paths = new HashSet<>(fsStore.list(OptOutUtils.prefixPartitionFile)); + + JsonObject config = make1mOptOutEntryConfig(); + + // Act + CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, clock) + .updateIndex(paths); + + // Assert + for (OptOutEntry entry : entries) { + assertEquals(entry.timestamp, snapshot.getAdIdOptOutTimestamp(entry.advertisingIdToB64())); + } + } + + private List createDelta(int entriesCount, Instant timestamp, MemCachedStorage fsStore) throws CloudStorageException { + return createDeltaOrPartition(entriesCount, timestamp, fsStore, OptOutUtils.newDeltaFileName(timestamp)); + } + + private List createPartition(int entriesCount, Instant timestamp, MemCachedStorage fsStore) throws CloudStorageException { + return createDeltaOrPartition(entriesCount, timestamp, fsStore, OptOutUtils.newPartitionFileName(timestamp)); + } + + private List createDeltaOrPartition(int entriesCount, Instant timestamp, MemCachedStorage fsStore, String cloudPath) throws CloudStorageException { + List entries = createEntries(timestamp, entriesCount); + fsStore.upload(new ByteArrayInputStream(entriesToByteArray(entries)), cloudPath); + return entries; + } + + private List createEntries(Instant timestamp, int count) { + List entries = new ArrayList<>(); + for (int i = 0; i < count; i++) { + entries.add(OptOutEntry.newTestEntry(timestamp.plusSeconds(i).toEpochMilli(), timestamp.plusSeconds(i).toEpochMilli())); + } + return entries; + } + + private byte[] entriesToByteArray(List entries) { + byte[] bytes = new byte[OptOutConst.EntrySize * entries.size()]; + for (int i = 0; i < entries.size(); i++) { + entries.get(i).copyToByteArray(bytes, OptOutConst.EntrySize * i); + } + return bytes; + } + + private JsonObject make1mOptOutEntryConfig() { + final JsonObject config = new JsonObject(); + config.put(Const.Config.OptOutBloomFilterSizeProp, 100000); // 1:10 bloomfilter + config.put(Const.Config.OptOutHeapDefaultCapacityProp, 1000000); // 1MM record + config.put("optout_delta_rotate_interval", 86400); + config.put("optout_partition_interval", 86400); + config.put("optout_max_partitions", 150); + return config; + } + } +} From 36df76d1d1bec1130b64cda5e682c05992a9f6f4 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 9 May 2024 08:05:02 +1000 Subject: [PATCH 0428/1116] Gave the skr container more cpu and memory --- scripts/azure-cc/deployment/operator.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/azure-cc/deployment/operator.json b/scripts/azure-cc/deployment/operator.json index 14ab9531d..428943e0c 100644 --- a/scripts/azure-cc/deployment/operator.json +++ b/scripts/azure-cc/deployment/operator.json @@ -102,8 +102,8 @@ ], "resources": { "requests": { - "cpu": 3.9, - "memoryInGB": 15.9 + "cpu": 3.5, + "memoryInGB": 15.5 } }, "environmentVariables": [ @@ -136,8 +136,8 @@ ], "resources": { "requests": { - "cpu": 0.1, - "memoryInGB": 0.1 + "cpu": 0.5, + "memoryInGB": 0.5 } }, "environmentVariables": [ From 63a983092585d1050df08612ac7cdb6ac0ce1ad4 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 8 May 2024 23:18:34 +0000 Subject: [PATCH 0429/1116] [CI Pipeline] Released Patch version: 5.32.16 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74d5782a9..bccd7c905 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.12 + 5.32.16 UTF-8 From 8cc2920abd83511d778b89614097121d177407fb Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 13 May 2024 11:17:53 +1000 Subject: [PATCH 0430/1116] UID2-3315 Change file path for syslog (#548) * Change file path for syslog * Change the name of the log files * Add logrotate config to the build * Remove logrotate in entrypoint.sh * Use syslg-ng-ctl to reload * Use custom branch for testing * Revert custom testing branch to main --- .github/actions/build_aws_eif/action.yaml | 1 + scripts/aws/logrotate/uid2operator-logrotate.conf | 12 ++++++++++++ scripts/aws/syslog-ng/syslog-ng-server.conf | 9 ++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 scripts/aws/logrotate/uid2operator-logrotate.conf diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 1610e7032..fb514effc 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -68,6 +68,7 @@ runs: cp ./scripts/aws/syslog-ng/syslog-ng-server.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/syslog-ng/server/syslog-ng-pubkey.gpg ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/syslog-ng/server/syslog-ng-4.6.0-1.el7.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/logrotate/uid2operator-logrotate.conf ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/scripts/aws/logrotate/uid2operator-logrotate.conf b/scripts/aws/logrotate/uid2operator-logrotate.conf new file mode 100644 index 000000000..7ebde6df1 --- /dev/null +++ b/scripts/aws/logrotate/uid2operator-logrotate.conf @@ -0,0 +1,12 @@ +/var/log/ip-*.log +{ + rotate 30 + daily + maxsize 30M + dateext dateformat -%Y-%m-%d-%s + notifempty + sharedscripts + postrotate + /usr/sbin/syslog-ng-ctl reload + endscript +} diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index 927e302db..91fef5caa 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -23,12 +23,15 @@ source s_network { ); }; -destination d_local { - file("/var/log/messages"); +destination d_file { + file( + "/var/log/${LOGHOST}.log" + dir-perm(0755) + template-escape(no)); }; log { source(s_local); source(s_network); - destination(d_local); + destination(d_file); }; From f5a73d89b7dfa56793102c5945ebe97df28b9f58 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 13 May 2024 01:32:37 +0000 Subject: [PATCH 0431/1116] [CI Pipeline] Released Patch version: 5.32.19 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bccd7c905..593a72416 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.16 + 5.32.19 UTF-8 From 7c572a72c7256ebf8cbe5829d4c20d8504e0cf91 Mon Sep 17 00:00:00 2001 From: Cody Constine Date: Mon, 13 May 2024 14:45:37 -0600 Subject: [PATCH 0432/1116] Adding the ability to diable CSTG key --- .../TokenResponseStatsCollector.java | 3 +- .../operator/vertx/UIDOperatorVerticle.java | 6 +++ .../operator/UIDOperatorVerticleTest.java | 50 ++++++++++++++++++- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 09af68a94..4e4880f6f 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -38,7 +38,8 @@ public enum ResponseStatus { PayloadHasNoBody, /* End of CSTG-related Status */ Unknown, - NoActiveKey + NoActiveKey, + UNAUTHORIZED } public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus) { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 8f2e20012..ee02f8709 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -337,6 +337,12 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA return; } + if(clientSideKeypair.isDisabled()) { + SendClientErrorResponseAndRecordStats(ResponseStatus.Unauthorized, 401, rc, "Unauthorized", + null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.UNAUTHORIZED, siteProvider); + return; + } + if (!hasValidOriginOrAppName(rc, request, clientSideKeypair)) { return; } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 1a57827d8..ccddb3cc7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -42,7 +42,6 @@ import io.vertx.ext.web.client.WebClient; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; -import org.apache.commons.collections4.CollectionUtils; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -3094,6 +3093,55 @@ void cstgLogsInvalidAppName(String appName, Vertx vertx, VertxTestContext testCo }); } + @Test + void catalogsDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); + this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); + + setupCstgBackend(); + String subscriptionID = "PpRrE5YY84"; + ClientSideKeypair keypairDisabled = new ClientSideKeypair(subscriptionID, clientSideTokenGeneratePublicKey, clientSideTokenGeneratePrivateKey, clientSideTokenGenerateSiteId, "", Instant.now(), true, ""); + when(clientSideKeypairProvider.getSnapshot()).thenReturn(clientSideKeypairSnapshot); + when(clientSideKeypairSnapshot.getKeypair(subscriptionID)).thenReturn(keypairDisabled); + + final KeyFactory kf = KeyFactory.getInstance("EC"); + final PublicKey serverPublicKey = ClientSideTokenGenerateTestUtil.stringToPublicKey(clientSideTokenGeneratePublicKey, kf); + final PrivateKey clientPrivateKey = ClientSideTokenGenerateTestUtil.stringToPrivateKey(clientSideTokenGeneratePrivateKey, kf); + final SecretKey secretKey = ClientSideTokenGenerateTestUtil.deriveKey(serverPublicKey, clientPrivateKey); + + final byte[] iv = Random.getBytes(12); + final long timestamp = Instant.now().toEpochMilli(); + final JsonArray aad = JsonArray.of(timestamp); + String rawId = "random@unifiedid.com"; + + JsonObject identityPayload = new JsonObject(); + identityPayload.put("email_hash", getSha256(rawId)); + byte[] payloadBytes = ClientSideTokenGenerateTestUtil.encrypt(identityPayload.toString().getBytes(), secretKey.getEncoded(), iv, aad.toBuffer().getBytes()); + final String payload = EncodingUtils.toBase64String(payloadBytes); + + JsonObject requestJson = new JsonObject(); + requestJson.put("payload", payload); + requestJson.put("iv", EncodingUtils.toBase64String(iv)); + requestJson.put("public_key", serverPublicKey.toString()); + requestJson.put("timestamp", timestamp); + requestJson.put("subscription_id", subscriptionID); + + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), false, null); + sendCstg(vertx, + "v2/token/client-generate", + null, + requestJson, + secretKey, + 401, + testContext, + respJson -> { + assertEquals("Unauthorized", respJson.getString("message")); + testContext.completeNow(); + }); + } + @ParameterizedTest @CsvSource({ "true,http://gototest.com", From 5bca3446be13fe78bd06f31b78d491ee3c63806e Mon Sep 17 00:00:00 2001 From: Cody Constine Date: Tue, 14 May 2024 16:10:46 -0600 Subject: [PATCH 0433/1116] Fixed broken test --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index ccddb3cc7..b3a549cf5 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -3108,7 +3108,7 @@ void catalogsDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) t final KeyFactory kf = KeyFactory.getInstance("EC"); final PublicKey serverPublicKey = ClientSideTokenGenerateTestUtil.stringToPublicKey(clientSideTokenGeneratePublicKey, kf); - final PrivateKey clientPrivateKey = ClientSideTokenGenerateTestUtil.stringToPrivateKey(clientSideTokenGeneratePrivateKey, kf); + final PrivateKey clientPrivateKey = ClientSideTokenGenerateTestUtil.stringToPrivateKey("MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDsqxZicsGytVqN2HZqNDHtV422Lxio8m1vlflq4Jb47Q==", kf); final SecretKey secretKey = ClientSideTokenGenerateTestUtil.deriveKey(serverPublicKey, clientPrivateKey); final byte[] iv = Random.getBytes(12); From 2871cb3a6bf65d38c9327495b9e352bc4282638d Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 15 May 2024 10:56:08 +1000 Subject: [PATCH 0434/1116] UID2-3261 Add logger to log information about (#561) * Add logger to log information about * Add information about site id to the logging * Add logging to v1 endpoint as well --- src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 8f2e20012..ad0e6e365 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1171,6 +1171,7 @@ private void handleBucketsV1(RoutingContext rc) { try { LocalDateTime ld = LocalDateTime.parse(qp.get(0), DateTimeFormatter.ISO_LOCAL_DATE_TIME); sinceTimestamp = ld.toInstant(ZoneOffset.UTC); + LOGGER.info(String.format("identity bucket endpoint is called with since_timestamp %s and site id $s", ld, AuthMiddleware.getAuthClient(rc).getSiteId())); } catch (Exception e) { ResponseUtil.ClientError(rc, "invalid date, must conform to ISO 8601"); return; @@ -1202,6 +1203,7 @@ private void handleBucketsV2(RoutingContext rc) { try { LocalDateTime ld = LocalDateTime.parse(qp, DateTimeFormatter.ISO_LOCAL_DATE_TIME); sinceTimestamp = ld.toInstant(ZoneOffset.UTC); + LOGGER.info(String.format("identity bucket endpoint is called with since_timestamp %s and site id $s", ld, AuthMiddleware.getAuthClient(rc).getSiteId())); } catch (Exception e) { ResponseUtil.ClientError(rc, "invalid date, must conform to ISO 8601"); return; From 6029a1b2d1772ce74515ada6c0dcadcc4581d3a7 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 15 May 2024 00:59:19 +0000 Subject: [PATCH 0435/1116] [CI Pipeline] Released Patch version: 5.32.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 593a72416..67be748ca 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.19 + 5.32.22 UTF-8 From 29970fbf40093297d37e95c0b7a8f283782d1a46 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 15 May 2024 15:22:06 +1000 Subject: [PATCH 0436/1116] UID2-3315 Update log names with operator prefix (#563) * Update log names with operator prefix * Rename logrotate config file without the uid2 prefix * Add logrotate cronjob file * Copy correct logrotate related files --- .github/actions/build_aws_eif/action.yaml | 3 ++- scripts/aws/logrotate/logrotate | 8 ++++++++ ...id2operator-logrotate.conf => operator-logrotate.conf} | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 scripts/aws/logrotate/logrotate rename scripts/aws/logrotate/{uid2operator-logrotate.conf => operator-logrotate.conf} (89%) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index fb514effc..55663e497 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -68,7 +68,8 @@ runs: cp ./scripts/aws/syslog-ng/syslog-ng-server.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/syslog-ng/server/syslog-ng-pubkey.gpg ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/syslog-ng/server/syslog-ng-4.6.0-1.el7.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/logrotate/uid2operator-logrotate.conf ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/logrotate/operator-logrotate.conf ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/logrotate/logrotate ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/scripts/aws/logrotate/logrotate b/scripts/aws/logrotate/logrotate new file mode 100644 index 000000000..967932eec --- /dev/null +++ b/scripts/aws/logrotate/logrotate @@ -0,0 +1,8 @@ +#!/bin/sh + +/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf +EXITVALUE=$? +if [ $EXITVALUE != 0 ]; then + /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" +fi +exit 0 diff --git a/scripts/aws/logrotate/uid2operator-logrotate.conf b/scripts/aws/logrotate/operator-logrotate.conf similarity index 89% rename from scripts/aws/logrotate/uid2operator-logrotate.conf rename to scripts/aws/logrotate/operator-logrotate.conf index 7ebde6df1..ce3bc53a6 100644 --- a/scripts/aws/logrotate/uid2operator-logrotate.conf +++ b/scripts/aws/logrotate/operator-logrotate.conf @@ -1,4 +1,4 @@ -/var/log/ip-*.log +/var/log/operator-ip-*.log { rotate 30 daily From 427d46d9a624a62115874c37799c91ab5798afcc Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 15 May 2024 05:22:51 +0000 Subject: [PATCH 0437/1116] [CI Pipeline] Released Patch version: 5.32.25 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 67be748ca..a0f26cf5c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.22 + 5.32.25 UTF-8 From ce3b04feac0edeccaefa3adaeaedce714018f67e Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Thu, 16 May 2024 14:48:50 +1000 Subject: [PATCH 0438/1116] UID2-3315 update logging destination (#565) * Change log name * Add crontab script * Copy crontab script in action * Use logrotate instead of modifying crontab * Add 0minutely file to run cronjob minutely * Use custom branch for testing * Run logrotate from the script * Renmae 0minutely to logrotate * Rename syslog-ng logs to operator.log * Change branch back to main --- scripts/aws/logrotate/logrotate | 13 +++++-------- scripts/aws/logrotate/operator-logrotate.conf | 2 +- scripts/aws/syslog-ng/syslog-ng-server.conf | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/scripts/aws/logrotate/logrotate b/scripts/aws/logrotate/logrotate index 967932eec..59b97872b 100644 --- a/scripts/aws/logrotate/logrotate +++ b/scripts/aws/logrotate/logrotate @@ -1,8 +1,5 @@ -#!/bin/sh - -/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf -EXITVALUE=$? -if [ $EXITVALUE != 0 ]; then - /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" -fi -exit 0 +# Run the minutely jobs +SHELL=/bin/bash +PATH=/sbin:/bin:/usr/sbin:/usr/bin +MAILTO=root +* * * * * root /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf diff --git a/scripts/aws/logrotate/operator-logrotate.conf b/scripts/aws/logrotate/operator-logrotate.conf index ce3bc53a6..73cec6719 100644 --- a/scripts/aws/logrotate/operator-logrotate.conf +++ b/scripts/aws/logrotate/operator-logrotate.conf @@ -1,4 +1,4 @@ -/var/log/operator-ip-*.log +/var/log/operator.log { rotate 30 daily diff --git a/scripts/aws/syslog-ng/syslog-ng-server.conf b/scripts/aws/syslog-ng/syslog-ng-server.conf index 91fef5caa..aa9b52e1c 100644 --- a/scripts/aws/syslog-ng/syslog-ng-server.conf +++ b/scripts/aws/syslog-ng/syslog-ng-server.conf @@ -25,7 +25,7 @@ source s_network { destination d_file { file( - "/var/log/${LOGHOST}.log" + "/var/log/operator.log" dir-perm(0755) template-escape(no)); }; From e476048d74d027fd3b724547308aca78b6ac0a66 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 16 May 2024 05:44:56 +0000 Subject: [PATCH 0439/1116] [CI Pipeline] Released Patch version: 5.32.28 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a0f26cf5c..81c604425 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.25 + 5.32.28 UTF-8 From 7e3366be178b7ad1a583c60d32b5c814217b5958 Mon Sep 17 00:00:00 2001 From: Asloob Qureshi Date: Thu, 16 May 2024 13:16:11 -0700 Subject: [PATCH 0440/1116] [UID2-2005] Add new endpoint to check opt out status by raw UIDs (#557) * Add new endpoint to check opt out status by raw UIDs * Try loading optout deltas from local * Revert "Try loading optout deltas from local" This reverts commit d8e563a247d9a265608ba84af872422cc6e856aa. * Add a switch to disable endpoint and hashmap loading * Add Snapshot store test for disabled status * Add test cases for optout status endpoint processing * Increase max request size to 5K. Refactor and update tests * Update opt out status test * Update default max size of opt out request --- conf/default-config.json | 2 + conf/local-config.json | 1 + conf/local-e2e-docker-public-config.json | 1 + src/main/java/com/uid2/operator/Const.java | 2 + .../operator/store/CloudSyncOptOutStore.java | 34 ++++-- .../com/uid2/operator/store/IOptOutStore.java | 2 + .../operator/vertx/UIDOperatorVerticle.java | 81 +++++++++++++- .../operator/UIDOperatorVerticleTest.java | 102 +++++++++++++++++- .../operator/benchmark/BenchmarkCommon.java | 5 + .../store/OptOutStoreSnapshotTest.java | 31 +++++- 10 files changed, 245 insertions(+), 16 deletions(-) diff --git a/conf/default-config.json b/conf/default-config.json index 6469529e9..44df29c6c 100644 --- a/conf/default-config.json +++ b/conf/default-config.json @@ -17,6 +17,8 @@ "optout_partition_interval": 86400, "optout_max_partitions": 30, "optout_heap_default_capacity": 8192, + "optout_status_api_enabled": false, + "optout_status_max_request_size": 5000, "cloud_download_threads": 8, "cloud_upload_threads": 2, "cloud_refresh_interval": 60, diff --git a/conf/local-config.json b/conf/local-config.json index 59332c650..a2146e9bc 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -32,6 +32,7 @@ "optout_heap_default_capacity": 8192, "optout_max_partitions": 30, "optout_partition_interval": 86400, + "optout_status_api_enabled": true, "client_side_token_generate": true, "client_side_token_generate_domain_name_check_enabled": true, "key_sharing_endpoint_provide_app_names": true, diff --git a/conf/local-e2e-docker-public-config.json b/conf/local-e2e-docker-public-config.json index af29da6f7..5b44ea981 100644 --- a/conf/local-e2e-docker-public-config.json +++ b/conf/local-e2e-docker-public-config.json @@ -31,6 +31,7 @@ "optout_metadata_path": "/optout/refresh", "optout_api_uri": "http://optout:8081/optout/replicate", "optout_delta_rotate_interval": 60, + "optout_status_api_enabled": true, "cloud_refresh_interval": 30, "salts_expired_shutdown_hours": 12 } diff --git a/src/main/java/com/uid2/operator/Const.java b/src/main/java/com/uid2/operator/Const.java index 0d5bd59b9..48dd16648 100644 --- a/src/main/java/com/uid2/operator/Const.java +++ b/src/main/java/com/uid2/operator/Const.java @@ -23,5 +23,7 @@ public class Config extends com.uid2.shared.Const.Config { public static final String AzureSecretNameProp = "azure_secret_name"; public static final String GcpSecretVersionNameProp = "gcp_secret_version_name"; + public static final String OptOutStatusApiEnabled = "optout_status_api_enabled"; + public static final String OptOutStatusMaxRequestSize = "optout_status_max_request_size"; } } diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index fe7ee3a2d..3f56ec1cd 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -79,6 +79,11 @@ public Instant getLatestEntry(UserIdentity firstLevelHashIdentity) { return instant; } + @Override + public long getOptOutTimestampByAdId(String adId) { + return this.snapshot.get().getAdIdOptOutTimestamp(adId); + } + @Override public void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { if (remoteApiHost == null) { @@ -344,6 +349,8 @@ public static class OptOutStoreSnapshot { */ private final Map adIdToOptOutTimestamp; + private final boolean optoutStatusApiEnabled; + // array of optout partitions private final OptOutPartition[] partitions; @@ -373,6 +380,7 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, this.heap = new OptOutHeap(heapCapacity); this.adIdToOptOutTimestamp = Collections.emptyMap(); + this.optoutStatusApiEnabled = jsonConfig.getBoolean(Const.Config.OptOutStatusApiEnabled, false); // initially 1 partition this.partitions = new OptOutPartition[1]; @@ -384,7 +392,8 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, } public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap heap, - OptOutPartition[] newPartitions, IndexUpdateContext iuc) { + OptOutPartition[] newPartitions, IndexUpdateContext iuc, + boolean optoutStatusApiEnabled) { this.clock = last.clock; this.fsLocal = last.fsLocal; this.fileUtils = last.fileUtils; @@ -400,14 +409,19 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap newIndexedFiles.addAll(iuc.loadedPartitions.keySet()); this.indexedFiles = Collections.unmodifiableSet(newIndexedFiles); - HashMap newOptOutTimestamps = new HashMap<>(); - for (OptOutPartition partition : this.partitions) { - if (partition == null) continue; - partition.forEach(entry -> { - newOptOutTimestamps.merge(entry.advertisingIdToB64(), entry.timestamp, OPT_OUT_TIMESTAMP_MERGE_STRATEGY); - }); + this.optoutStatusApiEnabled = optoutStatusApiEnabled; + if (this.optoutStatusApiEnabled) { + HashMap newOptOutTimestamps = new HashMap<>(); + for (OptOutPartition partition : this.partitions) { + if (partition == null) continue; + partition.forEach(entry -> { + newOptOutTimestamps.merge(entry.advertisingIdToB64(), entry.timestamp, OPT_OUT_TIMESTAMP_MERGE_STRATEGY); + }); + } + this.adIdToOptOutTimestamp = Collections.unmodifiableMap(newOptOutTimestamps); + } else { + this.adIdToOptOutTimestamp = Collections.emptyMap(); } - this.adIdToOptOutTimestamp = Collections.unmodifiableMap(newOptOutTimestamps); // update total entries totalEntries.set(size()); @@ -587,7 +601,7 @@ private OptOutStoreSnapshot processDeltas(IndexUpdateContext iuc) { newPartitions[0] = this.heap.isEmpty() ? null : this.heap.toPartition(true); OptOutStoreSnapshot.bloomFilterSize.set(this.bloomFilter.size()); - return new OptOutStoreSnapshot(this, this.bloomFilter, this.heap, newPartitions, iuc); + return new OptOutStoreSnapshot(this, this.bloomFilter, this.heap, newPartitions, iuc, this.optoutStatusApiEnabled); } private OptOutStoreSnapshot processPartitions(IndexUpdateContext iuc) { @@ -637,7 +651,7 @@ private OptOutStoreSnapshot processPartitions(IndexUpdateContext iuc) { OptOutStoreSnapshot.bloomFilterSize.set(newBf.size()); OptOutStoreSnapshot.bloomFilterMax.set(newBf.capacity()); - return new OptOutStoreSnapshot(this, newBf, newHeap, newPartitions, iuc); + return new OptOutStoreSnapshot(this, newBf, newHeap, newPartitions, iuc, this.optoutStatusApiEnabled); } // used for finding files to feed to index diff --git a/src/main/java/com/uid2/operator/store/IOptOutStore.java b/src/main/java/com/uid2/operator/store/IOptOutStore.java index ebd7b8ec2..cadfd239a 100644 --- a/src/main/java/com/uid2/operator/store/IOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/IOptOutStore.java @@ -15,5 +15,7 @@ public interface IOptOutStore { */ Instant getLatestEntry(UserIdentity firstLevelHashIdentity); + long getOptOutTimestampByAdId(String adId); + void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler); } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 178c5064b..35d1d2b21 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -101,6 +101,8 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final Map, Counter> _tokenGeneratePolicyCounters = new HashMap<>(); private final Map> _identityMapUnmappedIdentifiers = new HashMap<>(); private final Map _identityMapRequestWithUnmapped = new HashMap<>(); + + private final Map optOutStatusCounters = new HashMap<>(); private final IdentityScope identityScope; private final V2PayloadHandler v2PayloadHandler; private final boolean phoneSupport; @@ -121,6 +123,9 @@ public class UIDOperatorVerticle extends AbstractVerticle { protected boolean keySharingEndpointProvideAppNames; protected Instant lastInvalidOriginProcessTime = Instant.now(); + private final int optOutStatusMaxRequestSize; + private final boolean optOutStatusApiEnabled; + public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, ISiteStore siteProvider, @@ -168,6 +173,8 @@ public UIDOperatorVerticle(JsonObject config, this.allowClockSkewSeconds = config.getInteger(Const.Config.AllowClockSkewSecondsProp, 1800); this.maxSharingLifetimeSeconds = config.getInteger(Const.Config.MaxSharingLifetimeProp, config.getInteger(Const.Config.SharingTokenExpiryProp)); this.saltRetrievalResponseHandler = saltRetrievalResponseHandler; + this.optOutStatusApiEnabled = config.getBoolean(Const.Config.OptOutStatusApiEnabled, false); + this.optOutStatusMaxRequestSize = config.getInteger(Const.Config.OptOutStatusMaxRequestSize, 5000); } @Override @@ -278,7 +285,11 @@ private void setupV2Routes(Router mainRouter, BodyHandler bodyHandler) { rc -> v2PayloadHandler.handle(rc, this::handleKeysBidstream), Role.ID_READER)); v2Router.post("/token/logout").handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handleAsync(rc, this::handleLogoutAsyncV2), Role.OPTOUT)); - + if (this.optOutStatusApiEnabled) { + v2Router.post("/optout/status").handler(bodyHandler).handler(auth.handleV1( + rc -> v2PayloadHandler.handle(rc, this::handleOptoutStatus), + Role.MAPPER, Role.SHARER, Role.ID_READER)); + } if (this.clientSideTokenGenerate) v2Router.post("/token/client-generate").handler(bodyHandler).handler(this::handleClientSideTokenGenerate); @@ -1678,6 +1689,74 @@ private void recordIdentityMapStatsForServiceLinks(RoutingContext rc, String api } } + private List parseOptoutStatusRequestPayload(RoutingContext rc) { + final JsonObject requestObj = (JsonObject) rc.data().get("request"); + if (requestObj == null) { + ResponseUtil.Error(ResponseStatus.ClientError, HttpStatus.SC_BAD_REQUEST, rc, "Invalid request body"); + return null; + } + final JsonArray rawUidsJsonArray = requestObj.getJsonArray("advertising_ids"); + if (rawUidsJsonArray == null) { + ResponseUtil.Error(ResponseStatus.ClientError, HttpStatus.SC_BAD_REQUEST, rc, "Required Parameter Missing: advertising_ids"); + return null; + } + if (rawUidsJsonArray.size() > optOutStatusMaxRequestSize) { + ResponseUtil.Error(ResponseStatus.ClientError, HttpStatus.SC_BAD_REQUEST, rc, "Request payload is too large"); + return null; + } + List rawUID2sInputList = new ArrayList<>(rawUidsJsonArray.size()); + for (int i = 0; i < rawUidsJsonArray.size(); ++i) { + rawUID2sInputList.add(rawUidsJsonArray.getString(i)); + } + return rawUID2sInputList; + } + + private void handleOptoutStatus(RoutingContext rc) { + try { + // Parse request to get list of raw UID2 strings + List rawUID2sInput = parseOptoutStatusRequestPayload(rc); + if (rawUID2sInput == null) { + return; + } + final JsonArray optedOutJsonArray = new JsonArray(); + for (String rawUId : rawUID2sInput) { + // Call opt out service to get timestamp of opted out identities + long timestamp = optOutStore.getOptOutTimestampByAdId(rawUId); + if (timestamp != -1) { + JsonObject optOutJsonObj = new JsonObject(); + optOutJsonObj.put("advertising_id", rawUId); + optOutJsonObj.put("opted_out_since", timestamp); + optedOutJsonArray.add(optOutJsonObj); + } + } + // Create response and return + final JsonObject bodyJsonObj = new JsonObject(); + bodyJsonObj.put("opted_out", optedOutJsonArray); + ResponseUtil.SuccessV2(rc, bodyJsonObj); + recordOptOutStatusEndpointStats(rc, rawUID2sInput.size(), optedOutJsonArray.size()); + } catch (Exception e) { + ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, + "Unknown error while getting optout status", e); + } + } + + private void recordOptOutStatusEndpointStats(RoutingContext rc, int inputCount, int optOutCount) { + String apiContact = getApiContact(rc); + DistributionSummary inputDistSummary = optOutStatusCounters.computeIfAbsent(apiContact, k -> DistributionSummary + .builder("uid2.operator.optout.status.input_size") + .description("number of UIDs received in request") + .tags("api_contact", apiContact) + .register(Metrics.globalRegistry)); + inputDistSummary.record(inputCount); + + DistributionSummary optOutDistSummary = optOutStatusCounters.computeIfAbsent(apiContact, k -> DistributionSummary + .builder("uid2.operator.optout.status.optout_size") + .description("number of UIDs that have opted out") + .tags("api_contact", apiContact) + .register(Metrics.globalRegistry)); + optOutDistSummary.record(optOutCount); + } + private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { final RefreshToken refreshToken; try { diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 1a57827d8..4821a3ab6 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -42,7 +42,6 @@ import io.vertx.ext.web.client.WebClient; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; -import org.apache.commons.collections4.CollectionUtils; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -96,6 +95,8 @@ public class UIDOperatorVerticleTest { private static final String clientSideTokenGeneratePrivateKey = "UID2-Y-L-MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBop1Dw/IwDcstgicr/3tDoyR3OIpgAWgw8mD6oTO+1ug=="; private static final int clientSideTokenGenerateSiteId = 123; + private static final int optOutStatusMaxRequestSize = 1000; + private AutoCloseable mocks; @Mock private ISiteStore siteProvider; @Mock private IClientKeyProvider clientKeyProvider; @@ -159,6 +160,8 @@ private void setupConfig(JsonObject config) { config.put("client_side_token_generate_log_invalid_http_origins", true); config.put(Const.Config.AllowClockSkewSecondsProp, 3600); + config.put(Const.Config.OptOutStatusApiEnabled, true); + config.put(Const.Config.OptOutStatusMaxRequestSize, optOutStatusMaxRequestSize); } private static byte[] makeAesKey(String prefix) { @@ -2115,6 +2118,103 @@ void identityMapBatchRequestTooLarge(String apiVersion, Vertx vertx, VertxTestCo send(apiVersion, vertx, apiVersion + "/identity/map", false, null, req, 413, json -> testContext.completeNow()); } + private static Stream optOutStatusRequestData() { + List rawUIDS = Arrays.asList("RUQbFozFwnmPVjDx8VMkk9vJoNXUJImKnz2h9RfzzM24", + "qAmIGxqLk_RhOtm4f1nLlqYewqSma8fgvjEXYnQ3Jr0K", + "r3wW2uvJkwmeFcbUwSeM6BIpGF8tX38wtPfVc4wYyo71", + "e6SA-JVAXnvk8F1MUtzsMOyWuy5Xqe15rLAgqzSGiAbz"); + Map optedOutIdsCase1 = new HashMap<>(); + + optedOutIdsCase1.put(rawUIDS.get(0), Instant.now().minus(1, ChronoUnit.DAYS).getEpochSecond()); + optedOutIdsCase1.put(rawUIDS.get(1), Instant.now().minus(2, ChronoUnit.DAYS).getEpochSecond()); + optedOutIdsCase1.put(rawUIDS.get(2), -1L); + optedOutIdsCase1.put(rawUIDS.get(3), -1L); + + Map optedOutIdsCase2 = new HashMap<>(); + optedOutIdsCase2.put(rawUIDS.get(2), -1L); + optedOutIdsCase2.put(rawUIDS.get(3), -1L); + return Stream.of( + Arguments.arguments(optedOutIdsCase1, 2, Role.MAPPER), + Arguments.arguments(optedOutIdsCase1, 2, Role.ID_READER), + Arguments.arguments(optedOutIdsCase1, 2, Role.SHARER), + Arguments.arguments(optedOutIdsCase2, 0, Role.MAPPER) + ); + } + + @ParameterizedTest + @MethodSource("optOutStatusRequestData") + void optOutStatusRequest(Map optedOutIds, int optedOutCount, Role role, Vertx vertx, VertxTestContext testContext) { + fakeAuth(126, role); + setupSalts(); + setupKeys(); + + JsonArray rawUIDs = new JsonArray(); + for (String rawUID2 : optedOutIds.keySet()) { + when(this.optOutStore.getOptOutTimestampByAdId(rawUID2)).thenReturn(optedOutIds.get(rawUID2)); + rawUIDs.add(rawUID2); + } + JsonObject requestJson = new JsonObject(); + requestJson.put("advertising_ids", rawUIDs); + + send("v2", vertx, "v2/optout/status", false, null, requestJson, 200, respJson -> { + assertEquals("success", respJson.getString("status")); + JsonArray optOutJsonArray = respJson.getJsonObject("body").getJsonArray("opted_out"); + assertEquals(optedOutCount, optOutJsonArray.size()); + for (int i = 0; i < optOutJsonArray.size(); ++i) { + JsonObject optOutObject = optOutJsonArray.getJsonObject(i); + assertEquals(optedOutIds.get(optOutObject.getString("advertising_id")), + optOutObject.getLong("opted_out_since")); + } + testContext.completeNow(); + }); + } + + private static Stream optOutStatusValidationErrorData() { + // Test case 1 + JsonArray rawUIDs = new JsonArray(); + + for (int i = 0; i <= optOutStatusMaxRequestSize; ++i) { + byte[] rawUid2Bytes = Random.getBytes(32); + rawUIDs.add(Utils.toBase64String(rawUid2Bytes)); + } + + JsonObject requestJson1 = new JsonObject(); + requestJson1.put("advertising_ids", rawUIDs); + // Test case 2 + JsonObject requestJson2 = new JsonObject(); + requestJson2.put("advertising", rawUIDs); + return Stream.of( + Arguments.arguments(requestJson1, "Request payload is too large"), + Arguments.arguments(requestJson2, "Required Parameter Missing: advertising_ids") + ); + } + + @ParameterizedTest + @MethodSource("optOutStatusValidationErrorData") + void optOutStatusValidationError(JsonObject requestJson, String errorMsg, Vertx vertx, VertxTestContext testContext) { + fakeAuth(126, Role.MAPPER); + setupSalts(); + setupKeys(); + + send("v2", vertx, "v2/optout/status", false, null, requestJson, 400, respJson -> { + assertEquals(com.uid2.shared.Const.ResponseStatus.ClientError, respJson.getString("status")); + assertEquals(errorMsg, respJson.getString("message")); + testContext.completeNow(); + }); + } + + @Test + void optOutStatusUnauthorized(Vertx vertx, VertxTestContext testContext) { + fakeAuth(126, Role.GENERATOR); + setupSalts(); + setupKeys(); + + send("v2", vertx, "v2/optout/status", false, null, new JsonObject(), 401, respJson -> { + assertEquals(com.uid2.shared.Const.ResponseStatus.Unauthorized, respJson.getString("status")); + testContext.completeNow(); + }); + } + @Test void LogoutV2(Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 896190d3d..4cc327e9f 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -197,6 +197,11 @@ public Instant getLatestEntry(UserIdentity firstLevelHashIdentity) { public void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { // noop } + + @Override + public long getOptOutTimestampByAdId(String adId) { + return -1; + } } } diff --git a/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java b/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java index b27e36309..1202aa8dd 100644 --- a/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java +++ b/src/test/java/com/uid2/operator/store/OptOutStoreSnapshotTest.java @@ -31,7 +31,7 @@ class GetAdIdOptOutTimestamp { @Test void emptySnapshotReturnsNegativeOne() { DownloadCloudStorage fsStore = mock(DownloadCloudStorage.class); - JsonObject config = make1mOptOutEntryConfig(); + JsonObject config = make1mOptOutEntryConfig(true); CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, Clock.systemUTC()); assertEquals(-1L, snapshot.getAdIdOptOutTimestamp(OptOutEntry.newRandom().advertisingIdToB64())); } @@ -63,7 +63,7 @@ void emptySnapshotUpdatedWithDeltaFilesReturnsCorrectTimestamps(int deltaFileCou Set paths = new HashSet<>(fsStore.list(OptOutUtils.prefixDeltaFile)); - JsonObject config = make1mOptOutEntryConfig(); + JsonObject config = make1mOptOutEntryConfig(true); // Act CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, clock) @@ -102,7 +102,7 @@ void emptySnapshotUpdatedWithPartitionFilesReturnsCorrectTimestamps(int partitio Set paths = new HashSet<>(fsStore.list(OptOutUtils.prefixPartitionFile)); - JsonObject config = make1mOptOutEntryConfig(); + JsonObject config = make1mOptOutEntryConfig(true); // Act CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, clock) @@ -114,6 +114,28 @@ void emptySnapshotUpdatedWithPartitionFilesReturnsCorrectTimestamps(int partitio } } + @Test + void optoutStatusApiDisabled() throws CloudStorageException, IOException { + int entriesPerPartitionFileCount = 10; + MemCachedStorage fsStore = new MemCachedStorage(); + + Clock clock = Clock.fixed(Instant.parse("2024-05-06T10:15:30.00Z"), ZoneOffset.UTC); + List entries = createPartition(entriesPerPartitionFileCount, clock.instant(), fsStore); + + Set paths = new HashSet<>(fsStore.list(OptOutUtils.prefixPartitionFile)); + + JsonObject config = make1mOptOutEntryConfig(false); + + // Act + CloudSyncOptOutStore.OptOutStoreSnapshot snapshot = new CloudSyncOptOutStore.OptOutStoreSnapshot(fsStore, config, clock) + .updateIndex(paths); + + // Assert + for (OptOutEntry entry : entries) { + assertEquals(-1L, snapshot.getAdIdOptOutTimestamp(entry.advertisingIdToB64())); + } + } + private List createDelta(int entriesCount, Instant timestamp, MemCachedStorage fsStore) throws CloudStorageException { return createDeltaOrPartition(entriesCount, timestamp, fsStore, OptOutUtils.newDeltaFileName(timestamp)); } @@ -144,8 +166,9 @@ private byte[] entriesToByteArray(List entries) { return bytes; } - private JsonObject make1mOptOutEntryConfig() { + private JsonObject make1mOptOutEntryConfig(boolean optOutStatusApiEnabled) { final JsonObject config = new JsonObject(); + config.put(Const.Config.OptOutStatusApiEnabled, optOutStatusApiEnabled); config.put(Const.Config.OptOutBloomFilterSizeProp, 100000); // 1:10 bloomfilter config.put(Const.Config.OptOutHeapDefaultCapacityProp, 1000000); // 1MM record config.put("optout_delta_rotate_interval", 86400); From 77aa46b9f1d4fd4d061db4f167f4913b9972ccb1 Mon Sep 17 00:00:00 2001 From: mcollins-ttd <118872455+mcollins-ttd@users.noreply.github.com> Date: Fri, 17 May 2024 06:19:16 +1000 Subject: [PATCH 0441/1116] Create new optout metrics (#560) - Number of advertising IDs. - Time to query optout timestamp by advertising ID. - Time to query optout timestamp by first-level hash. - Labelled by the Bloom filter's answer. - Time to process delta files. - Time to process partition files. --- .../operator/store/CloudSyncOptOutStore.java | 88 ++++++++++++++----- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 3f56ec1cd..e43039380 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -12,9 +12,8 @@ import com.uid2.shared.cloud.ICloudStorage; import com.uid2.shared.cloud.MemCachedStorage; import com.uid2.shared.optout.*; -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Gauge; -import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.*; +import io.micrometer.core.instrument.Timer; import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; @@ -33,11 +32,13 @@ import java.time.Clock; import java.time.Instant; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; import java.util.function.BinaryOperator; import java.util.function.Function; +import java.util.function.LongSupplier; import java.util.stream.Collectors; public class CloudSyncOptOutStore implements IOptOutStore { @@ -297,33 +298,58 @@ public Collection getLoadedPartitions() { public static class OptOutStoreSnapshot { private static final Logger LOGGER = LoggerFactory.getLogger(OptOutStoreSnapshot.class); - private static final Gauge gaugeEntriesIndexed = Gauge - .builder("uid2.optout.entries_indexed", () -> OptOutStoreSnapshot.totalEntries.get()) + private static final String METRIC_NAME_PREFIX = "uid2.optout."; + + // Metrics for processing deltas and partitions. + private static final String OPT_OUT_PROCESSING_METRIC_NAME = METRIC_NAME_PREFIX + "processing"; + + private static final Timer DELTA_PROCESSING = Metrics.timer(OPT_OUT_PROCESSING_METRIC_NAME, "file_type", "deltas"); + + private static final Timer PARTITION_PROCESSING = Metrics.timer(OPT_OUT_PROCESSING_METRIC_NAME, "file_type", "partitions"); + + // Metrics for querying optout timestamp by advertising ID. + private static final Timer GET_AD_ID_OPT_OUT_TIMESTAMP = Metrics.timer(METRIC_NAME_PREFIX + "get_ad_id_optout_timestamp"); + + private static final Gauge AD_ID_COUNT = Gauge.builder(METRIC_NAME_PREFIX + "ad_id_count", () -> OptOutStoreSnapshot.adIdCount.get()) + .register(Metrics.globalRegistry); + + // Metrics for querying optout timestamp by first-level hash. + private static final String GET_OPT_OUT_TIMESTAMP_METRIC_NAME = METRIC_NAME_PREFIX + "get_optout_timestamp"; + + private static final Timer GET_OPT_OUT_TIMESTAMP_FALSE_POSITIVE = Metrics.timer(GET_OPT_OUT_TIMESTAMP_METRIC_NAME, "bloom_filter", "false_positive"); + + private static final Timer GET_OPT_OUT_TIMESTAMP_TRUE_POSITIVE = Metrics.timer(GET_OPT_OUT_TIMESTAMP_METRIC_NAME, "bloom_filter", "true_positive"); + + private static final Timer GET_OPT_OUT_TIMESTAMP_TRUE_NEGATIVE = Metrics.timer(GET_OPT_OUT_TIMESTAMP_METRIC_NAME, "bloom_filter", "true_negative"); + + private static final Gauge GAUGE_ENTRIES_INDEXED = Gauge + .builder(METRIC_NAME_PREFIX + "entries_indexed", () -> OptOutStoreSnapshot.totalEntries.get()) .description("gauge for how many optout entries are indexed") .register(Metrics.globalRegistry); - private static final Counter counterDeltasIndexed = Counter - .builder("uid2.optout.deltas_indexed") + private static final Counter COUNTER_DELTAS_INDEXED = Counter + .builder(METRIC_NAME_PREFIX + "deltas_indexed") .description("counter for how many optout delta files are indexed") .register(Metrics.globalRegistry); - private static final Counter counterPartitionsIndexed = Counter - .builder("uid2.optout.partitions_indexed") + private static final Counter COUNTER_PARTITIONS_INDEXED = Counter + .builder(METRIC_NAME_PREFIX + "partitions_indexed") .description("counter for how many optout parition files are indexed") .register(Metrics.globalRegistry); - private static final Counter counterIndexUpdated = Counter - .builder("uid2.optout.index_updated") + private static final Counter COUNTER_INDEX_UPDATED = Counter + .builder(METRIC_NAME_PREFIX + "index_updated") .description("counter for how many times index is updated") .register(Metrics.globalRegistry); - private static final Gauge gaugeBloomfilterSize = Gauge - .builder("uid2.optout.bloomfilter_size", () -> OptOutStoreSnapshot.bloomFilterSize.get()) + // Metrics for the Bloom filter. + private static final Gauge GAUGE_BLOOMFILTER_SIZE = Gauge + .builder(METRIC_NAME_PREFIX + "bloomfilter_size", () -> OptOutStoreSnapshot.bloomFilterSize.get()) .description("gauge for number of entries cached in bloomfilter") .register(Metrics.globalRegistry); - private static final Gauge gaugeBloomfilterMax = Gauge - .builder("uid2.optout.bloomfilter_max", () -> OptOutStoreSnapshot.bloomFilterMax.get()) + private static final Gauge GAUGE_BLOOMFILTER_MAX = Gauge + .builder(METRIC_NAME_PREFIX + "bloomfilter_max", () -> OptOutStoreSnapshot.bloomFilterMax.get()) .description("gauge for max entries can be cached in bloomfilter") .register(Metrics.globalRegistry); @@ -332,6 +358,7 @@ public static class OptOutStoreSnapshot { private static final AtomicLong bloomFilterSize = new AtomicLong(0); private static final AtomicLong bloomFilterMax = new AtomicLong(0); private static final AtomicLong totalEntries = new AtomicLong(0); + private static final AtomicInteger adIdCount = new AtomicInteger(0); private static final BiFunction OPT_OUT_TIMESTAMP_MERGE_STRATEGY = Long::min; private final DownloadCloudStorage fsLocal; @@ -425,6 +452,7 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap // update total entries totalEntries.set(size()); + adIdCount.set(this.adIdToOptOutTimestamp.size()); } public long size() { @@ -441,7 +469,8 @@ public boolean isHealthy(Instant now) { } public long getAdIdOptOutTimestamp(String advertisingId) { - return this.adIdToOptOutTimestamp.getOrDefault(advertisingId, -1L); + LongSupplier supplier = () -> this.adIdToOptOutTimestamp.getOrDefault(advertisingId, -1L); + return GET_AD_ID_OPT_OUT_TIMESTAMP.record(supplier); } // method provided for OptOutService to call @@ -451,18 +480,27 @@ public long getOptOutTimestamp(byte[] hashBytes) { // ones hash is a special case, we will always return -1 for ones hash (0xff...ff) if (Arrays.equals(hashBytes, OptOutUtils.onesHashBytes)) return -1; + Timer.Sample sample = Timer.start(); + if (!this.bloomFilter.likelyContains(hashBytes)) { - // bloom filter says no, which would be final + // Bloom filter says no, which would be final. + sample.stop(GET_OPT_OUT_TIMESTAMP_TRUE_NEGATIVE); return -1; } for (OptOutPartition s : this.partitions) { if (s == null) continue; long ts = s.getOptOutTimestamp(hashBytes); - if (ts != -1) return ts; + if (ts != -1) { + // "True positive": The Bloom filter said we likely have the optout record, and we do. + sample.stop(GET_OPT_OUT_TIMESTAMP_TRUE_POSITIVE); + return ts; + } } // not found any where, return not found + // "False positive": The Bloom filter said we likely have the optout record, and we don't. + sample.stop(GET_OPT_OUT_TIMESTAMP_FALSE_POSITIVE); return -1; } @@ -572,13 +610,17 @@ private OptOutStoreSnapshot updateIndexInternal(IndexUpdateContext iuc) { IndexUpdateMessage result = iuc.result(); this.updateIndexTimestamp(result.lastTimestamp()); - this.counterPartitionsIndexed.increment(numPartitions); - this.counterDeltasIndexed.increment(result.getDeltasToAdd().size()); - this.counterIndexUpdated.increment(); + COUNTER_PARTITIONS_INDEXED.increment(numPartitions); + COUNTER_DELTAS_INDEXED.increment(result.getDeltasToAdd().size()); + COUNTER_INDEX_UPDATED.increment(); } } private OptOutStoreSnapshot processDeltas(IndexUpdateContext iuc) { + return DELTA_PROCESSING.record(() -> processDeltasImpl(iuc)); + } + + private OptOutStoreSnapshot processDeltasImpl(IndexUpdateContext iuc) { Collection loadedData = iuc.getLoadedDeltas(); if (loadedData.size() == 0) return this; @@ -605,6 +647,10 @@ private OptOutStoreSnapshot processDeltas(IndexUpdateContext iuc) { } private OptOutStoreSnapshot processPartitions(IndexUpdateContext iuc) { + return PARTITION_PROCESSING.record(() -> processPartitionsImpl(iuc)); + } + + private OptOutStoreSnapshot processPartitionsImpl(IndexUpdateContext iuc) { int newSnaps = iuc.getLoadedPartitions().size(); if (newSnaps == 0) return this; From aedffb9807e6e52edcc7f9febc668b657cd399b6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 17 May 2024 17:25:39 +0000 Subject: [PATCH 0442/1116] [CI Pipeline] Released Minor version: 5.33.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 81c604425..94dd263f7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.32.28 + 5.33.0 UTF-8 diff --git a/version.json b/version.json index 8eaf5b013..57f82eccf 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.32", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.33", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From b8afc57a3f760307007aa97f786bf1b5ca624006 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 20 May 2024 17:00:52 +1000 Subject: [PATCH 0443/1116] Fix logrotate config regex error (#579) --- scripts/aws/logrotate/operator-logrotate.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/logrotate/operator-logrotate.conf b/scripts/aws/logrotate/operator-logrotate.conf index 73cec6719..52faeea64 100644 --- a/scripts/aws/logrotate/operator-logrotate.conf +++ b/scripts/aws/logrotate/operator-logrotate.conf @@ -1,4 +1,4 @@ -/var/log/operator.log +/var/log/operator.log* { rotate 30 daily From 1ead5cdd3073a0542de796a3fa3aed80b7c7c3dc Mon Sep 17 00:00:00 2001 From: Cody Constine Date: Mon, 20 May 2024 09:53:05 -0600 Subject: [PATCH 0444/1116] Addressing PR comments, fixing up the test --- .../TokenResponseStatsCollector.java | 2 +- .../operator/vertx/UIDOperatorVerticle.java | 2 +- .../uid2/operator/UIDOperatorVerticleTest.java | 18 +++++++----------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 4e4880f6f..bd6f10edf 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -39,7 +39,7 @@ public enum ResponseStatus { /* End of CSTG-related Status */ Unknown, NoActiveKey, - UNAUTHORIZED + Unauthorized } public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus) { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index ee02f8709..59c46bae6 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -339,7 +339,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA if(clientSideKeypair.isDisabled()) { SendClientErrorResponseAndRecordStats(ResponseStatus.Unauthorized, 401, rc, "Unauthorized", - null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.UNAUTHORIZED, siteProvider); + clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unauthorized, siteProvider); return; } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b3a549cf5..33d8339fb 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -3094,7 +3094,7 @@ void cstgLogsInvalidAppName(String appName, Vertx vertx, VertxTestContext testCo } @Test - void catalogsDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + void cstgDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { ListAppender logWatcher = new ListAppender<>(); logWatcher.start(); ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); @@ -3110,20 +3110,12 @@ void catalogsDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) t final PublicKey serverPublicKey = ClientSideTokenGenerateTestUtil.stringToPublicKey(clientSideTokenGeneratePublicKey, kf); final PrivateKey clientPrivateKey = ClientSideTokenGenerateTestUtil.stringToPrivateKey("MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDsqxZicsGytVqN2HZqNDHtV422Lxio8m1vlflq4Jb47Q==", kf); final SecretKey secretKey = ClientSideTokenGenerateTestUtil.deriveKey(serverPublicKey, clientPrivateKey); - - final byte[] iv = Random.getBytes(12); final long timestamp = Instant.now().toEpochMilli(); - final JsonArray aad = JsonArray.of(timestamp); - String rawId = "random@unifiedid.com"; - JsonObject identityPayload = new JsonObject(); - identityPayload.put("email_hash", getSha256(rawId)); - byte[] payloadBytes = ClientSideTokenGenerateTestUtil.encrypt(identityPayload.toString().getBytes(), secretKey.getEncoded(), iv, aad.toBuffer().getBytes()); - final String payload = EncodingUtils.toBase64String(payloadBytes); JsonObject requestJson = new JsonObject(); - requestJson.put("payload", payload); - requestJson.put("iv", EncodingUtils.toBase64String(iv)); + requestJson.put("payload", ""); + requestJson.put("iv", ""); requestJson.put("public_key", serverPublicKey.toString()); requestJson.put("timestamp", timestamp); requestJson.put("subscription_id", subscriptionID); @@ -3138,6 +3130,10 @@ void catalogsDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) t testContext, respJson -> { assertEquals("Unauthorized", respJson.getString("message")); + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.Unauthorized); testContext.completeNow(); }); } From 505697604bd1fe812c8378b48fb9692500e6da96 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 21 May 2024 20:30:21 +0000 Subject: [PATCH 0445/1116] [CI Pipeline] Released Minor version: 5.34.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 94dd263f7..2082565f6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.33.0 + 5.34.0 UTF-8 diff --git a/version.json b/version.json index 57f82eccf..e84dc69db 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.33", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.34", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From d1e33b7f61d8ce1abab59a3f767cceae140f64ad Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Fri, 24 May 2024 08:05:46 +1000 Subject: [PATCH 0446/1116] Change typo $s to %s (#581) --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 298edb47e..1b7023db2 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1188,7 +1188,7 @@ private void handleBucketsV1(RoutingContext rc) { try { LocalDateTime ld = LocalDateTime.parse(qp.get(0), DateTimeFormatter.ISO_LOCAL_DATE_TIME); sinceTimestamp = ld.toInstant(ZoneOffset.UTC); - LOGGER.info(String.format("identity bucket endpoint is called with since_timestamp %s and site id $s", ld, AuthMiddleware.getAuthClient(rc).getSiteId())); + LOGGER.info(String.format("identity bucket endpoint is called with since_timestamp %s and site id %s", ld, AuthMiddleware.getAuthClient(rc).getSiteId())); } catch (Exception e) { ResponseUtil.ClientError(rc, "invalid date, must conform to ISO 8601"); return; @@ -1220,7 +1220,7 @@ private void handleBucketsV2(RoutingContext rc) { try { LocalDateTime ld = LocalDateTime.parse(qp, DateTimeFormatter.ISO_LOCAL_DATE_TIME); sinceTimestamp = ld.toInstant(ZoneOffset.UTC); - LOGGER.info(String.format("identity bucket endpoint is called with since_timestamp %s and site id $s", ld, AuthMiddleware.getAuthClient(rc).getSiteId())); + LOGGER.info(String.format("identity bucket endpoint is called with since_timestamp %s and site id %s", ld, AuthMiddleware.getAuthClient(rc).getSiteId())); } catch (Exception e) { ResponseUtil.ClientError(rc, "invalid date, must conform to ISO 8601"); return; From 6ccf14d53cfed8d3bf2f4eecb7857d9d0cb81a88 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Sun, 26 May 2024 14:48:08 -0700 Subject: [PATCH 0447/1116] Add metrics info for Mobile CSTGi --- .../TokenResponseStatsCollector.java | 23 +++-- .../uid2/operator/service/ResponseUtil.java | 12 +-- .../operator/vertx/UIDOperatorVerticle.java | 83 ++++++++++--------- .../uid2/operator/vertx/V2PayloadHandler.java | 4 +- .../operator/UIDOperatorVerticleTest.java | 79 ++++++++++++------ 5 files changed, 117 insertions(+), 84 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index bd6f10edf..7f8405cc6 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -42,11 +42,17 @@ public enum ResponseStatus { Unauthorized } - public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus) { - recordInternal(siteStore, siteId, endpoint, responseStatus, advertisingTokenVersion, endpoint == Endpoint.ClientSideTokenGenerateV2); + public enum PlatformType { + Unknown, + Mobile, + Web + } + + public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus, PlatformType platformType) { + recordInternal(siteStore, siteId, endpoint, responseStatus, advertisingTokenVersion, endpoint == Endpoint.ClientSideTokenGenerateV2, platformType); } - private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoint endpoint, ResponseStatus responseStatus, TokenVersion advertisingTokenVersion, boolean isCstg) { + private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoint endpoint, ResponseStatus responseStatus, TokenVersion advertisingTokenVersion, boolean isCstg, PlatformType platformType) { if (siteId == null) return; var builder = Counter @@ -57,7 +63,8 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin "token_endpoint", String.valueOf(endpoint), "token_response_status", String.valueOf(responseStatus), "advertising_token_version", String.valueOf(advertisingTokenVersion), - "cstg", isCstg ? "true" : "false"); + "cstg", isCstg ? "true" : "false", + "platformType", String.valueOf(platformType)); builder.register(Metrics.globalRegistry).increment(); } @@ -65,14 +72,14 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, RefreshResponse refreshResponse) { if (!refreshResponse.isRefreshed()) { if (refreshResponse.isOptOut() || refreshResponse.isDeprecated()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg()); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); } else if (refreshResponse.isInvalidToken()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg()); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); } else if (refreshResponse.isExpired()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg()); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); } } else { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg()); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); } } } diff --git a/src/main/java/com/uid2/operator/service/ResponseUtil.java b/src/main/java/com/uid2/operator/service/ResponseUtil.java index aa9040b22..6a091f6f9 100644 --- a/src/main/java/com/uid2/operator/service/ResponseUtil.java +++ b/src/main/java/com/uid2/operator/service/ResponseUtil.java @@ -68,21 +68,21 @@ public static void ClientError(RoutingContext rc, String message) { Warning(ResponseStatus.ClientError, 400, rc, message); } - public static void SendClientErrorResponseAndRecordStats(String errorStatus, int statusCode, RoutingContext rc, String message, Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider) + public static void SendClientErrorResponseAndRecordStats(String errorStatus, int statusCode, RoutingContext rc, String message, Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, TokenResponseStatsCollector.PlatformType platformType) { Warning(errorStatus, statusCode, rc, message); - recordTokenResponseStats(siteId, endpoint, responseStatus, siteProvider, null); + recordTokenResponseStats(siteId, endpoint, responseStatus, siteProvider, null, platformType); } - public static void SendServerErrorResponseAndRecordStats(RoutingContext rc, String message, Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, Exception exception) + public static void SendServerErrorResponseAndRecordStats(RoutingContext rc, String message, Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, Exception exception, TokenResponseStatsCollector.PlatformType platformType) { Error(ResponseStatus.UnknownError, 500, rc, message, exception); rc.fail(500); - recordTokenResponseStats(siteId, endpoint, responseStatus, siteProvider, null); + recordTokenResponseStats(siteId, endpoint, responseStatus, siteProvider, null, platformType); } - public static void recordTokenResponseStats(Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, TokenVersion advertisingTokenVersion) { - TokenResponseStatsCollector.record(siteProvider, siteId, endpoint, advertisingTokenVersion, responseStatus); + public static void recordTokenResponseStats(Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, TokenVersion advertisingTokenVersion, TokenResponseStatsCollector.PlatformType platformType) { + TokenResponseStatsCollector.record(siteProvider, siteId, endpoint, advertisingTokenVersion, responseStatus, platformType); } public static JsonObject Response(String status, String message) { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 298edb47e..942ae76fb 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -301,7 +301,7 @@ private void handleClientSideTokenGenerate(RoutingContext rc) { try { handleClientSideTokenGenerateImpl(rc); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while handling client side token generate", null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while handling client side token generate", null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } @@ -329,37 +329,38 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA body = rc.body().asJsonObject(); } catch (DecodeException ex) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "json payload is not valid", - null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadJsonPayload, siteProvider); + null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadJsonPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } if (body == null) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "json payload expected but not found", - null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.PayloadHasNoBody, siteProvider); + null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.PayloadHasNoBody, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } final CstgRequest request = body.mapTo(CstgRequest.class); + final TokenResponseStatsCollector.PlatformType platformType = request.getAppName() == null ? TokenResponseStatsCollector.PlatformType.Web : TokenResponseStatsCollector.PlatformType.Mobile; final ClientSideKeypair clientSideKeypair = this.clientSideKeypairProvider.getSnapshot().getKeypair(request.getSubscriptionId()); if (clientSideKeypair == null) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad subscription_id", - null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadSubscriptionId, siteProvider); + null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadSubscriptionId, siteProvider, platformType); return; } if(clientSideKeypair.isDisabled()) { SendClientErrorResponseAndRecordStats(ResponseStatus.Unauthorized, 401, rc, "Unauthorized", - clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unauthorized, siteProvider); + clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unauthorized, siteProvider, platformType); return; } - if (!hasValidOriginOrAppName(rc, request, clientSideKeypair)) { + if (!hasValidOriginOrAppName(rc, request, clientSideKeypair, platformType)) { return; } if (request.getPayload() == null || request.getIv() == null || request.getPublicKey() == null) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "required parameters: payload, iv, public_key", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "required parameters: payload, iv, public_key", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, platformType); return; } @@ -371,7 +372,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA final X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(clientPublicKeyBytes); clientPublicKey = kf.generatePublic(pkSpec); } catch (Exception e) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad public key", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPublicKey, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad public key", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPublicKey, siteProvider, platformType); return; } @@ -387,11 +388,11 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA try { ivBytes = Base64.getDecoder().decode(request.getIv()); if (ivBytes.length != 12) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad iv", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadIV, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad iv", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadIV, siteProvider, platformType); return; } } catch (IllegalArgumentException e) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad iv", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadIV, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "bad iv", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadIV, siteProvider, platformType); return; } @@ -407,7 +408,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA System.arraycopy(encryptedPayloadBytes, 0, ivAndCiphertext, 12, encryptedPayloadBytes.length); requestPayloadBytes = decrypt(ivAndCiphertext, 0, sharedSecret, aad.toBuffer().getBytes()); } catch (Exception e) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "payload decryption failed", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "payload decryption failed", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, platformType); return; } @@ -415,7 +416,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA try { requestPayload = new JsonObject(Buffer.buffer(Unpooled.wrappedBuffer(requestPayloadBytes))); } catch (DecodeException e) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "encrypted payload contains invalid json", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "encrypted payload contains invalid json", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, platformType); return; } @@ -427,17 +428,17 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA if (phoneHash != null && !phoneSupport) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "phone support not enabled", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "phone support not enabled", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, platformType); return; } final String errString = phoneSupport ? "please provide exactly one of: email_hash, phone_hash" : "please provide email_hash"; if (emailHash == null && phoneHash == null) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, errString, clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, errString, clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, platformType); return; } else if (emailHash != null && phoneHash != null) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, errString, clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, errString, clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, platformType); return; } else if(emailHash != null) { @@ -463,7 +464,7 @@ else if(emailHash != null) { input.toUserIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), OptoutCheckPolicy.RespectOptOut)); } catch (KeyManager.NoActiveKeyException e){ - SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, platformType); return; } JsonObject response; @@ -490,10 +491,10 @@ else if(emailHash != null) { } final byte[] encryptedResponse = AesGcm.encrypt(response.toBuffer().getBytes(), sharedSecret); rc.response().setStatusCode(200).end(Buffer.buffer(Unpooled.wrappedBuffer(Base64.getEncoder().encode(encryptedResponse)))); - recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityTokens.getAdvertisingTokenVersion()); + recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityTokens.getAdvertisingTokenVersion(), platformType); } - private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair) { + private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair, TokenResponseStatsCollector.PlatformType platformType) { final OriginOrAppNameValidationResult validationResult = validateOriginOrAppName(rc, request, keypair); if (validationResult.isSuccess) { return true; @@ -502,7 +503,7 @@ private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, if (clientSideTokenGenerateLogInvalidHttpOrigin) { logInvalidOriginOrAppName(keypair.getSiteId(), validationResult.originOrAppName); } - SendClientErrorResponseAndRecordStats(validationResult.errorStatus, 403, rc, validationResult.message, keypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, validationResult.responseStatus, siteProvider); + SendClientErrorResponseAndRecordStats(validationResult.errorStatus, 403, rc, validationResult.message, keypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, validationResult.responseStatus, siteProvider, platformType); return false; } @@ -807,7 +808,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { final List tokenList = rc.queryParam("refresh_token"); Integer siteId = null; if (tokenList == null || tokenList.size() == 0) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } @@ -818,7 +819,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { if (v2req.isValid()) { refreshToken = (String) v2req.payload; } else { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, v2req.errorMessage, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, v2req.errorMessage, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } } @@ -846,7 +847,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, r); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } @@ -867,7 +868,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { } else if (r.isExpired()) { ResponseUtil.Warning(ResponseStatus.ExpiredToken, 400, rc, "Expired Token presented"); } else if (r.noActiveKey()) { - SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new KeyManager.NoActiveKeyException("No active encryption key available")); + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new KeyManager.NoActiveKeyException("No active encryption key available"), TokenResponseStatsCollector.PlatformType.Unknown); } else { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } @@ -877,7 +878,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token v2", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token v2", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } @@ -957,10 +958,10 @@ private void handleTokenGenerateV1(RoutingContext rc) { //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); ResponseUtil.Success(rc, toJsonV1(t)); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); } } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } @@ -977,12 +978,12 @@ private void handleTokenGenerateV2(RoutingContext rc) { switch (validateUserConsent(req)) { case INVALID: { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "User consent is invalid", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidUserConsentString, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "User consent is invalid", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidUserConsentString, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } case INSUFFICIENT: { ResponseUtil.SuccessNoBodyV2(ResponseStatus.InsufficientUserConsent, rc); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InsufficientUserConsent, siteProvider, null); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InsufficientUserConsent, siteProvider, null, TokenResponseStatsCollector.PlatformType.Unknown); return; } case SUFFICIENT: { @@ -998,7 +999,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { recordTokenGeneratePolicy(apiContact, optoutCheckPolicy.getItem1(), optoutCheckPolicy.getItem2()); if (!meetPolicyCheckRequirements(rc)) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required opt-out policy argument for token/generate is missing or not set to 1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required opt-out policy argument for token/generate is missing or not set to 1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } @@ -1025,22 +1026,22 @@ private void handleTokenGenerateV2(RoutingContext rc) { OptoutCheckPolicy.DoNotRespect)); ResponseUtil.SuccessV2(rc, toJsonV1(optOutTokens)); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); } else { // new participant, or legacy specified policy/optout_check=1 ResponseUtil.SuccessNoBodyV2("optout", rc); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, siteProvider, null); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, siteProvider, null, TokenResponseStatsCollector.PlatformType.Unknown); } } else { ResponseUtil.SuccessV2(rc, toJsonV1(t)); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); } } } catch (KeyManager.NoActiveKeyException e) { - SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } catch (ClientInputValidationException cie) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "request body contains invalid argument(s)", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "request body contains invalid argument(s)", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v2", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v2", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } @@ -1048,11 +1049,11 @@ private void handleTokenGenerate(RoutingContext rc) { final InputUtil.InputVal input = this.getTokenInput(rc); Integer siteId = null; if (input == null) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: exactly one of email or email_hash must be specified", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: exactly one of email or email_hash must be specified", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } else if (!input.isValid()) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Invalid email or email_hash", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Invalid email or email_hash", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } @@ -1066,11 +1067,11 @@ else if (!input.isValid()) { //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); sendJsonResponse(rc, toJson(t)); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } @@ -1078,7 +1079,7 @@ private void handleTokenRefresh(RoutingContext rc) { final List tokenList = rc.queryParam("refresh_token"); Integer siteId = null; if (tokenList == null || tokenList.size() == 0) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } @@ -1093,7 +1094,7 @@ private void handleTokenRefresh(RoutingContext rc) { } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, r); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); } } diff --git a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java index e59e49619..68e12b2d1 100644 --- a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java +++ b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java @@ -87,7 +87,7 @@ public void handleTokenGenerate(RoutingContext rc, Handler apiHa V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc), new InstantClock()); if (!request.isValid()) { - SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } rc.data().put("request", request.payload); @@ -126,7 +126,7 @@ public void handleTokenRefresh(RoutingContext rc, Handler apiHan if (bodyString != null && bodyString.length() == V2RequestUtil.V2_REFRESH_PAYLOAD_LENGTH) { request = V2RequestUtil.parseRefreshRequest(bodyString, this.keyManager); if (!request.isValid()) { - SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider); + SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); return; } rc.data().put("request", request.payload); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 4dea59d6a..eb41d8467 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -569,13 +569,14 @@ private static void assertEqualsClose(Instant expected, Instant actual, int with assertTrue(expected.plusSeconds(withinSeconds).isAfter(actual)); } - private void assertTokenStatusMetrics(Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus) { + private void assertTokenStatusMetrics(Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, TokenResponseStatsCollector.PlatformType platformType) { final double actual = Metrics.globalRegistry .get("uid2_token_response_status_count") .tag("site_id", String.valueOf(siteId)) .tag("token_endpoint", String.valueOf(endpoint)) .tag("token_response_status", String.valueOf(responseStatus)) .tag("advertising_token_version", responseStatus == TokenResponseStatsCollector.ResponseStatus.Success ? String.valueOf(getTokenVersion()) : "null") + .tag("platformType", String.valueOf(platformType)) .counter().count(); assertEquals(1, actual); } @@ -1146,7 +1147,8 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi assertTokenStatusMetrics( 201, TokenResponseStatsCollector.Endpoint.GenerateV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Unknown); sendTokenRefresh("v2", vertx, testContext, body.getString("refresh_token"), body.getString("refresh_response_key"), 200, refreshRespJson -> { @@ -1156,7 +1158,8 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi assertTokenStatusMetrics( 201, TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.OptOut); + TokenResponseStatsCollector.ResponseStatus.OptOut, + TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }); }); @@ -1289,11 +1292,13 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.GenerateV1 : TokenResponseStatsCollector.Endpoint.GenerateV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Unknown); assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }); @@ -1346,11 +1351,13 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.GenerateV1 : TokenResponseStatsCollector.Endpoint.GenerateV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Unknown); assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Unknown); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); @@ -1589,7 +1596,8 @@ void tokenRefreshNoToken(String apiVersion, Vertx vertx, VertxTestContext testCo assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.InvalidToken); + TokenResponseStatsCollector.ResponseStatus.InvalidToken, + TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }); } @@ -1605,7 +1613,8 @@ void tokenRefreshInvalidTokenAuthenticated(String apiVersion, Vertx vertx, Vertx assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.InvalidToken); + TokenResponseStatsCollector.ResponseStatus.InvalidToken, + TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }); } @@ -1733,7 +1742,8 @@ void tokenRefreshOptOut(String apiVersion, Vertx vertx, VertxTestContext testCon assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.OptOut); + TokenResponseStatsCollector.ResponseStatus.OptOut, + TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }); }); @@ -2600,7 +2610,7 @@ void tokenRefreshOptOutForPhone(String apiVersion, Vertx vertx, VertxTestContext assertEquals(200, response.statusCode()); JsonObject json = response.bodyAsJsonObject(); assertEquals("optout", json.getString("status")); - assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.OptOut); + assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.OptOut, TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }))); @@ -2892,7 +2902,7 @@ void tokenGenerateRespectOptOutOption(String policyParameterKey, Vertx vertx, Ve try { Assertions.assertEquals(ResponseUtil.ResponseStatus.OptOut, json.getString("status")); Assertions.assertNull(json.getJsonObject("body")); - assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut); + assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); } catch (Exception e) { testContext.failNow(e); @@ -3073,7 +3083,8 @@ void cstgNoIdentityHashProvided(Vertx vertx, VertxTestContext testContext) throw assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.MissingParams); + TokenResponseStatsCollector.ResponseStatus.MissingParams, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3102,7 +3113,8 @@ void cstgDomainNameCheckFails(boolean setOptoutCheckFlagInRequest, String httpOr assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin); + TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3133,7 +3145,8 @@ void cstgAppNameCheckFails(String appName, Vertx vertx, VertxTestContext testCon assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.InvalidAppName); + TokenResponseStatsCollector.ResponseStatus.InvalidAppName, + TokenResponseStatsCollector.PlatformType.Mobile); testContext.completeNow(); }); } @@ -3166,7 +3179,8 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagI assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin); + TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3234,7 +3248,8 @@ void cstgDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throw assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.Unauthorized); + TokenResponseStatsCollector.ResponseStatus.Unauthorized, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3275,7 +3290,8 @@ void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(boolean setOptoutChe assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin); + TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3451,7 +3467,8 @@ void cstgBadPublicKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAl assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadPublicKey); + TokenResponseStatsCollector.ResponseStatus.BadPublicKey, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3537,7 +3554,8 @@ void cstgBadIvNotBase64(Vertx vertx, VertxTestContext testContext) throws NoSuch assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadIV); + TokenResponseStatsCollector.ResponseStatus.BadIV, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3582,7 +3600,8 @@ void cstgBadIvIncorrectLength(Vertx vertx, VertxTestContext testContext) throws assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadIV); + TokenResponseStatsCollector.ResponseStatus.BadIV, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3624,7 +3643,8 @@ void cstgBadEncryptedPayload(Vertx vertx, VertxTestContext testContext) throws N assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadPayload); + TokenResponseStatsCollector.ResponseStatus.BadPayload, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3664,7 +3684,8 @@ void cstgInvalidEncryptedPayloadJson(Vertx vertx, VertxTestContext testContext) assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadPayload); + TokenResponseStatsCollector.ResponseStatus.BadPayload, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3708,7 +3729,8 @@ void cstgPhoneAndEmailProvided(Vertx vertx, VertxTestContext testContext) throws assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadPayload); + TokenResponseStatsCollector.ResponseStatus.BadPayload, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3753,7 +3775,8 @@ void cstgNoPhoneSupport(Vertx vertx, VertxTestContext testContext) throws NoSuch assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.BadPayload); + TokenResponseStatsCollector.ResponseStatus.BadPayload, + TokenResponseStatsCollector.PlatformType.Web); testContext.completeNow(); }); } @@ -3976,7 +3999,8 @@ else if(identityType == IdentityType.Phone) { assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Web); String genRefreshToken = genBody.getString("refresh_token"); //test a subsequent refresh from this cstg call and see if it still works @@ -4019,7 +4043,8 @@ else if(identityType == IdentityType.Phone) { assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.RefreshV2, - TokenResponseStatsCollector.ResponseStatus.Success); + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.Unknown); testContext.completeNow(); }); From 20c0ec31f5d3407c5b4ca588e33aff220de7086f Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 28 May 2024 11:10:49 +1000 Subject: [PATCH 0448/1116] UID2-3406 Add logging for origin and referer to 4xx warnings (#586) * Add logging for origin and referer to 4xx warnings * [CI Pipeline] Released Snapshot version: 5.34.1-alpha-77-SNAPSHOT --------- Co-authored-by: Release Workflow --- pom.xml | 2 +- .../uid2/operator/service/ResponseUtil.java | 15 +++- .../service/RoutingContextReader.java | 4 + .../operator/service/ResponseUtilTest.java | 87 ++++++++++++++++++- 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2082565f6..7db73c1ea 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.34.0 + 5.34.1-alpha-77-SNAPSHOT UTF-8 diff --git a/src/main/java/com/uid2/operator/service/ResponseUtil.java b/src/main/java/com/uid2/operator/service/ResponseUtil.java index aa9040b22..acaa1503e 100644 --- a/src/main/java/com/uid2/operator/service/ResponseUtil.java +++ b/src/main/java/com/uid2/operator/service/ResponseUtil.java @@ -152,7 +152,7 @@ private static void logError(String errorStatus, int statusCode, String message, } private static void logWarning(String status, int statusCode, String message, RoutingContextReader contextReader, String clientAddress) { - String warnMessage = "Warning response to http request. " + JsonObject.of( + JsonObject warnMessageJsonObject = JsonObject.of( "errorStatus", status, "contact", contextReader.getContact(), "siteId", contextReader.getSiteId(), @@ -160,7 +160,18 @@ private static void logWarning(String status, int statusCode, String message, Ro "statusCode", statusCode, "clientAddress", clientAddress, "message", message - ).encode(); + ); + final String referer = contextReader.getReferer(); + final String origin = contextReader.getOrigin(); + if (statusCode >= 400 && statusCode < 500) { + if (referer != null) { + warnMessageJsonObject.put("referer", referer); + } + if (origin != null) { + warnMessageJsonObject.put("origin", origin); + } + } + String warnMessage = "Warning response to http request. " + warnMessageJsonObject.encode(); LOGGER.warn(warnMessage); } diff --git a/src/main/java/com/uid2/operator/service/RoutingContextReader.java b/src/main/java/com/uid2/operator/service/RoutingContextReader.java index ba187a68b..054f11b72 100644 --- a/src/main/java/com/uid2/operator/service/RoutingContextReader.java +++ b/src/main/java/com/uid2/operator/service/RoutingContextReader.java @@ -13,6 +13,10 @@ public RoutingContextReader(RoutingContext context) { this.context = context; } + public String getOrigin() { return this.context.request().getHeader("origin"); } + + public String getReferer() { return this.context.request().getHeader("referer"); } + public Integer getSiteId() { final Integer siteId = context.get(Const.RoutingContextData.SiteId); if (siteId != null) { diff --git a/src/test/java/com/uid2/operator/service/ResponseUtilTest.java b/src/test/java/com/uid2/operator/service/ResponseUtilTest.java index 4d80387bc..103dd73a6 100644 --- a/src/test/java/com/uid2/operator/service/ResponseUtilTest.java +++ b/src/test/java/com/uid2/operator/service/ResponseUtilTest.java @@ -6,6 +6,7 @@ import ch.qos.logback.core.read.ListAppender; import com.uid2.shared.Const; import com.uid2.shared.auth.IAuthorizable; +import io.vertx.core.http.HttpServerRequest; import io.vertx.ext.web.RoutingContext; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -19,6 +20,7 @@ class ResponseUtilTest { private Logger logger; private ListAppender testAppender; private RoutingContext rc; + private HttpServerRequest request; @BeforeEach void setUp() { @@ -27,6 +29,7 @@ void setUp() { testAppender.start(); logger.addAppender(testAppender); rc = mock(RoutingContext.class, RETURNS_DEEP_STUBS); + request = mock(HttpServerRequest.class, RETURNS_DEEP_STUBS); when(rc.get(SecureLinkValidatorService.SERVICE_LINK_NAME, "")).thenReturn(""); when(rc.get(SecureLinkValidatorService.SERVICE_NAME, "")).thenReturn(""); } @@ -135,4 +138,86 @@ void logsErrorWithServiceAndServiceLinkNames() { ILoggingEvent loggingEvent = testAppender.list.get(0); assertThat(loggingEvent.getMessage()).isEqualTo(expected); } -} \ No newline at end of file + + @Test + void logsWarningWithOrigin() { + when(request.getHeader("origin")).thenReturn("testOriginHeader"); + when(rc.request()).thenReturn(request); + + ResponseUtil.Warning("Some error status", 400, rc, "Some error message"); + + String expected = "Warning response to http request. {" + + "\"errorStatus\":\"Some error status\"," + + "\"contact\":null," + + "\"siteId\":null," + + "\"path\":null," + + "\"statusCode\":400," + + "\"clientAddress\":null," + + "\"message\":\"Some error message\"," + + "\"origin\":\"testOriginHeader\"" + + "}"; + ILoggingEvent loggingEvent = testAppender.list.get(0); + assertThat(loggingEvent.getMessage()).isEqualTo(expected); + } + + @Test + void logsWarningWithOriginNull() { + when(request.getHeader("origin")).thenReturn(null); + when(rc.request()).thenReturn(request); + + ResponseUtil.Warning("Some error status", 400, rc, "Some error message"); + + String expected = "Warning response to http request. {" + + "\"errorStatus\":\"Some error status\"," + + "\"contact\":null," + + "\"siteId\":null," + + "\"path\":null," + + "\"statusCode\":400," + + "\"clientAddress\":null," + + "\"message\":\"Some error message\"" + + "}"; + ILoggingEvent loggingEvent = testAppender.list.get(0); + assertThat(loggingEvent.getMessage()).isEqualTo(expected); + } + + @Test + void logsWarningWithReferer() { + when(request.getHeader("referer")).thenReturn("testRefererHeader"); + when(rc.request()).thenReturn(request); + + ResponseUtil.Warning("Some error status", 400, rc, "Some error message"); + + String expected = "Warning response to http request. {" + + "\"errorStatus\":\"Some error status\"," + + "\"contact\":null," + + "\"siteId\":null," + + "\"path\":null," + + "\"statusCode\":400," + + "\"clientAddress\":null," + + "\"message\":\"Some error message\"," + + "\"referer\":\"testRefererHeader\"" + + "}"; + ILoggingEvent loggingEvent = testAppender.list.get(0); + assertThat(loggingEvent.getMessage()).isEqualTo(expected); + } + + @Test + void logsWarningWithRefererNull() { + when(request.getHeader("referer")).thenReturn(null); + when(rc.request()).thenReturn(request); + + ResponseUtil.Warning("Some error status", 400, rc, "Some error message"); + + String expected = "Warning response to http request. {" + + "\"errorStatus\":\"Some error status\"," + + "\"contact\":null," + + "\"siteId\":null," + + "\"path\":null," + + "\"statusCode\":400," + + "\"clientAddress\":null," + + "\"message\":\"Some error message\"" + + "}"; + ILoggingEvent loggingEvent = testAppender.list.get(0); + assertThat(loggingEvent.getMessage()).isEqualTo(expected); + } +} From f177ba41b3018883b0f284fc87f69a4cd84b9e2d Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 28 May 2024 01:13:26 +0000 Subject: [PATCH 0449/1116] [CI Pipeline] Released Patch version: 5.34.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7db73c1ea..9b7f73794 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.34.1-alpha-77-SNAPSHOT + 5.34.4 UTF-8 From 32240946e416f017054ed5e6302e84eab2afac45 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 28 May 2024 15:45:59 -0600 Subject: [PATCH 0450/1116] check query string for client version --- .../vertx/ClientVersionCapturingHandler.java | 15 +++---- .../operator/UIDOperatorVerticleTest.java | 41 +++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/ClientVersionCapturingHandler.java b/src/main/java/com/uid2/operator/vertx/ClientVersionCapturingHandler.java index 6ff5e6135..2af4fb6b2 100644 --- a/src/main/java/com/uid2/operator/vertx/ClientVersionCapturingHandler.java +++ b/src/main/java/com/uid2/operator/vertx/ClientVersionCapturingHandler.java @@ -32,13 +32,14 @@ public ClientVersionCapturingHandler(String dir, String whitelistGlob) throws IO } @Override public void handle(RoutingContext context) { - if (context.request().headers().contains(Const.Http.ClientVersionHeader)) { - final String clientVersion = context.request().headers().get(Const.Http.ClientVersionHeader); - if (clientVersion != null) { - final Counter counter = _clientVersionCounters.get(clientVersion); - if (counter != null) { - counter.increment(); - } + String clientVersion = context.request().headers().get(Const.Http.ClientVersionHeader); + if (clientVersion == null) { + clientVersion = !context.queryParam("client").isEmpty() ? context.queryParam("client").get(0) : null; + } + if (clientVersion != null) { + final Counter counter = _clientVersionCounters.get(clientVersion); + if (counter != null) { + counter.increment(); } } context.next(); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 4dea59d6a..d9986e592 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -5005,4 +5005,45 @@ void secureLinkValidationFailsReturnsIdentityError(Vertx vertx, VertxTestContext testContext.completeNow(); }); } + + @ParameterizedTest // note that this test will be removed when we switch to logging versions + @ValueSource(strings = {"euid-sdk-1.0.0", "openid-sdk-1.0", "uid2-esp-0.0.1a", "uid2-sdk-0.0.1a", + "uid2-sdk-0.0.1b", "uid2-sdk-1.0.0", "uid2-sdk-2.0.0"}) + void clientVersionHeader(String clientVersion, Vertx vertx, VertxTestContext testContext) { + WebClient client = WebClient.create(vertx); + ClientKey ck = clientKeyProvider.getClientKey(""); + HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint")); + if (ck != null) + req.putHeader("Authorization", "Bearer " + clientKey); + req.putHeader("X-UID2-Client-Version", clientVersion); + req.send(ar -> { + assertEquals(404, ar.result().statusCode()); + final double actual = Metrics.globalRegistry + .get("uid2.client_sdk_versions") + .tag("client_version", clientVersion) + .counter().count(); + assertEquals(1, actual); + testContext.completeNow(); + }); + } + + @ParameterizedTest // note that this test will be removed when we switch to logging versions + @ValueSource(strings = {"euid-sdk-1.0.0", "openid-sdk-1.0", "uid2-esp-0.0.1a", "uid2-sdk-0.0.1a", + "uid2-sdk-0.0.1b", "uid2-sdk-1.0.0", "uid2-sdk-2.0.0"}) + void clientVersionQueryParameter(String clientVersion, Vertx vertx, VertxTestContext testContext) { + WebClient client = WebClient.create(vertx); + ClientKey ck = clientKeyProvider.getClientKey(""); + HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint?client=" + clientVersion)); + if (ck != null) + req.putHeader("Authorization", "Bearer " + clientKey); + req.send(ar -> { + assertEquals(404, ar.result().statusCode()); + final double actual = Metrics.globalRegistry + .get("uid2.client_sdk_versions") + .tag("client_version", clientVersion) + .counter().count(); + assertEquals(1, actual); + testContext.completeNow(); + }); + } } From b12bd8f926d13dc82939519eac0c65e909cc3013 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 28 May 2024 15:49:41 -0600 Subject: [PATCH 0451/1116] don't need client key --- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index d9986e592..07279a828 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -5011,10 +5011,7 @@ void secureLinkValidationFailsReturnsIdentityError(Vertx vertx, VertxTestContext "uid2-sdk-0.0.1b", "uid2-sdk-1.0.0", "uid2-sdk-2.0.0"}) void clientVersionHeader(String clientVersion, Vertx vertx, VertxTestContext testContext) { WebClient client = WebClient.create(vertx); - ClientKey ck = clientKeyProvider.getClientKey(""); HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint")); - if (ck != null) - req.putHeader("Authorization", "Bearer " + clientKey); req.putHeader("X-UID2-Client-Version", clientVersion); req.send(ar -> { assertEquals(404, ar.result().statusCode()); @@ -5032,10 +5029,7 @@ void clientVersionHeader(String clientVersion, Vertx vertx, VertxTestContext tes "uid2-sdk-0.0.1b", "uid2-sdk-1.0.0", "uid2-sdk-2.0.0"}) void clientVersionQueryParameter(String clientVersion, Vertx vertx, VertxTestContext testContext) { WebClient client = WebClient.create(vertx); - ClientKey ck = clientKeyProvider.getClientKey(""); HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint?client=" + clientVersion)); - if (ck != null) - req.putHeader("Authorization", "Bearer " + clientKey); req.send(ar -> { assertEquals(404, ar.result().statusCode()); final double actual = Metrics.globalRegistry From 1d060650f963df457338094a036eaea4c972da67 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Tue, 28 May 2024 22:38:56 -0700 Subject: [PATCH 0452/1116] Add platformType for refresh and generate endpoint too --- .../TokenResponseStatsCollector.java | 16 ++-- .../operator/vertx/UIDOperatorVerticle.java | 79 ++++++++++++------- .../uid2/operator/vertx/V2PayloadHandler.java | 4 +- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 7f8405cc6..3b99586fb 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -43,9 +43,9 @@ public enum ResponseStatus { } public enum PlatformType { - Unknown, - Mobile, - Web + InApp, + HasOriginHeader, + Other } public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus, PlatformType platformType) { @@ -69,17 +69,17 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin builder.register(Metrics.globalRegistry).increment(); } - public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, RefreshResponse refreshResponse) { + public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, RefreshResponse refreshResponse, PlatformType platformType) { if (!refreshResponse.isRefreshed()) { if (refreshResponse.isOptOut() || refreshResponse.isDeprecated()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } else if (refreshResponse.isInvalidToken()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } else if (refreshResponse.isExpired()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } } else { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), PlatformType.Unknown); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } } } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 942ae76fb..5cdebcd27 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -301,7 +301,7 @@ private void handleClientSideTokenGenerate(RoutingContext rc) { try { handleClientSideTokenGenerateImpl(rc); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while handling client side token generate", null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while handling client side token generate", null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Other); } } @@ -325,22 +325,23 @@ private Set getAppNames(ClientSideKeypair keypair) { private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchAlgorithmException, InvalidKeyException { final JsonObject body; + TokenResponseStatsCollector.PlatformType platformType = TokenResponseStatsCollector.PlatformType.Other; try { + platformType = getPlatformType(rc); body = rc.body().asJsonObject(); } catch (DecodeException ex) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "json payload is not valid", - null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadJsonPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadJsonPayload, siteProvider, platformType); return; } if (body == null) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "json payload expected but not found", - null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.PayloadHasNoBody, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + null, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.PayloadHasNoBody, siteProvider, platformType); return; } final CstgRequest request = body.mapTo(CstgRequest.class); - final TokenResponseStatsCollector.PlatformType platformType = request.getAppName() == null ? TokenResponseStatsCollector.PlatformType.Web : TokenResponseStatsCollector.PlatformType.Mobile; final ClientSideKeypair clientSideKeypair = this.clientSideKeypairProvider.getSnapshot().getKeypair(request.getSubscriptionId()); if (clientSideKeypair == null) { @@ -806,9 +807,10 @@ private void handleHealthCheck(RoutingContext rc) { private void handleTokenRefreshV1(RoutingContext rc) { final List tokenList = rc.queryParam("refresh_token"); + TokenResponseStatsCollector.PlatformType platformType = getPlatformType(rc); Integer siteId = null; if (tokenList == null || tokenList.size() == 0) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, platformType); return; } @@ -819,7 +821,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { if (v2req.isValid()) { refreshToken = (String) v2req.payload; } else { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, v2req.errorMessage, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, v2req.errorMessage, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, platformType); return; } } @@ -845,15 +847,17 @@ private void handleTokenRefreshV1(RoutingContext rc) { this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains("Origin")); } - TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, r); + TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, r, platformType); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, platformType); } } private void handleTokenRefreshV2(RoutingContext rc) { Integer siteId = null; + TokenResponseStatsCollector.PlatformType platformType = TokenResponseStatsCollector.PlatformType.Other; try { + platformType = getPlatformType(rc); String tokenStr = (String) rc.data().get("request"); final RefreshResponse r = this.refreshIdentity(rc, tokenStr); siteId = rc.get(Const.RoutingContextData.SiteId); @@ -868,7 +872,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { } else if (r.isExpired()) { ResponseUtil.Warning(ResponseStatus.ExpiredToken, 400, rc, "Expired Token presented"); } else if (r.noActiveKey()) { - SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new KeyManager.NoActiveKeyException("No active encryption key available"), TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, new KeyManager.NoActiveKeyException("No active encryption key available"), platformType); } else { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } @@ -876,9 +880,9 @@ private void handleTokenRefreshV2(RoutingContext rc) { ResponseUtil.SuccessV2(rc, toJsonV1(r.getTokens())); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains("Origin")); } - TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r); + TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r, platformType); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token v2", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token v2", siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, platformType); } } @@ -944,8 +948,10 @@ private void handleTokenValidateV2(RoutingContext rc) { private void handleTokenGenerateV1(RoutingContext rc) { final int siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); + TokenResponseStatsCollector.PlatformType platformType = TokenResponseStatsCollector.PlatformType.Other; try { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); + platformType = getPlatformType(rc); if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { return; } else { @@ -958,17 +964,19 @@ private void handleTokenGenerateV1(RoutingContext rc) { //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); ResponseUtil.Success(rc, toJsonV1(t)); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), platformType); } } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, platformType); } } private void handleTokenGenerateV2(RoutingContext rc) { final Integer siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); + TokenResponseStatsCollector.PlatformType platformType = TokenResponseStatsCollector.PlatformType.Other; try { JsonObject req = (JsonObject) rc.data().get("request"); + platformType = getPlatformType(rc); final InputUtil.InputVal input = this.getTokenInputV2(req); if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { @@ -978,12 +986,12 @@ private void handleTokenGenerateV2(RoutingContext rc) { switch (validateUserConsent(req)) { case INVALID: { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "User consent is invalid", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidUserConsentString, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "User consent is invalid", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidUserConsentString, siteProvider, platformType); return; } case INSUFFICIENT: { ResponseUtil.SuccessNoBodyV2(ResponseStatus.InsufficientUserConsent, rc); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InsufficientUserConsent, siteProvider, null, TokenResponseStatsCollector.PlatformType.Unknown); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.InsufficientUserConsent, siteProvider, null, platformType); return; } case SUFFICIENT: { @@ -999,7 +1007,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { recordTokenGeneratePolicy(apiContact, optoutCheckPolicy.getItem1(), optoutCheckPolicy.getItem2()); if (!meetPolicyCheckRequirements(rc)) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required opt-out policy argument for token/generate is missing or not set to 1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required opt-out policy argument for token/generate is missing or not set to 1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, platformType); return; } @@ -1026,22 +1034,22 @@ private void handleTokenGenerateV2(RoutingContext rc) { OptoutCheckPolicy.DoNotRespect)); ResponseUtil.SuccessV2(rc, toJsonV1(optOutTokens)); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion(), platformType); } else { // new participant, or legacy specified policy/optout_check=1 ResponseUtil.SuccessNoBodyV2("optout", rc); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, siteProvider, null, TokenResponseStatsCollector.PlatformType.Unknown); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, siteProvider, null, platformType); } } else { ResponseUtil.SuccessV2(rc, toJsonV1(t)); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), platformType); } } } catch (KeyManager.NoActiveKeyException e) { - SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, platformType); } catch (ClientInputValidationException cie) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "request body contains invalid argument(s)", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "request body contains invalid argument(s)", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, platformType); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v2", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v2", siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, e, platformType); } } @@ -1049,11 +1057,11 @@ private void handleTokenGenerate(RoutingContext rc) { final InputUtil.InputVal input = this.getTokenInput(rc); Integer siteId = null; if (input == null) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: exactly one of email or email_hash must be specified", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: exactly one of email or email_hash must be specified", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Other); return; } else if (!input.isValid()) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Invalid email or email_hash", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Invalid email or email_hash", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Other); return; } @@ -1067,11 +1075,11 @@ else if (!input.isValid()) { //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Unknown); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Other); sendJsonResponse(rc, toJson(t)); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Other); } } @@ -1079,7 +1087,7 @@ private void handleTokenRefresh(RoutingContext rc) { final List tokenList = rc.queryParam("refresh_token"); Integer siteId = null; if (tokenList == null || tokenList.size() == 0) { - SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "Required Parameter Missing: refresh_token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.MissingParams, siteProvider, TokenResponseStatsCollector.PlatformType.Other); return; } @@ -1092,9 +1100,9 @@ private void handleTokenRefresh(RoutingContext rc) { if (r.isRefreshed()) { this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains("Origin")); } - TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, r); + TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, r, TokenResponseStatsCollector.PlatformType.Other); } catch (Exception e) { - SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Unknown); + SendServerErrorResponseAndRecordStats(rc, "Unknown error while refreshing token", siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Other); } } @@ -1787,13 +1795,24 @@ private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { } public static String getSiteName(ISiteStore siteStore, Integer siteId) { - if (siteId == null) return "unknown"; + if (siteId == null) return "X-UID2-Client-Version"; if (siteStore == null) return "unknown"; //this is expected if CSTG is not enabled, eg for private operators final Site site = siteStore.getSite(siteId); return (site == null) ? "unknown" : site.getName(); } + private TokenResponseStatsCollector.PlatformType getPlatformType(RoutingContext rc) { + final String clientVersion = rc.request().getHeader("X-UID2-Client-Version"); + if (clientVersion != null && (clientVersion.contains("Android") || clientVersion.contains("ios") || clientVersion.contains("tvos"))) { + return TokenResponseStatsCollector.PlatformType.InApp; + } + + final String origin = rc.request().getHeader("origin"); + + return origin != null ? TokenResponseStatsCollector.PlatformType.HasOriginHeader : TokenResponseStatsCollector.PlatformType.Other; + } + private void recordRefreshDurationStats(Integer siteId, String apiContact, Duration durationSinceLastRefresh, boolean hasOriginHeader) { DistributionSummary ds = _refreshDurationMetricSummaries.computeIfAbsent(new Tuple.Tuple2<>(apiContact, hasOriginHeader), k -> DistributionSummary diff --git a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java index 68e12b2d1..07ab3ff58 100644 --- a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java +++ b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java @@ -87,7 +87,7 @@ public void handleTokenGenerate(RoutingContext rc, Handler apiHa V2RequestUtil.V2Request request = V2RequestUtil.parseRequest(rc.body().asString(), AuthMiddleware.getAuthClient(ClientKey.class, rc), new InstantClock()); if (!request.isValid()) { - SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Other); return; } rc.data().put("request", request.payload); @@ -126,7 +126,7 @@ public void handleTokenRefresh(RoutingContext rc, Handler apiHan if (bodyString != null && bodyString.length() == V2RequestUtil.V2_REFRESH_PAYLOAD_LENGTH) { request = V2RequestUtil.parseRefreshRequest(bodyString, this.keyManager); if (!request.isValid()) { - SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Unknown); + SendClientErrorResponseAndRecordStats(ResponseUtil.ResponseStatus.ClientError, 400, rc, request.errorMessage, null, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, siteProvider, TokenResponseStatsCollector.PlatformType.Other); return; } rc.data().put("request", request.payload); From 150ad16f5ae5411853adce8f7fc150999262b5df Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 29 May 2024 15:22:47 -0600 Subject: [PATCH 0453/1116] client version not found test --- .../operator/UIDOperatorVerticleTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 07279a828..b0c8999f7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -27,7 +27,9 @@ import com.uid2.shared.secret.KeyHasher; import com.uid2.shared.store.*; import com.uid2.shared.store.reader.RotatingKeysetProvider; +import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.search.MeterNotFoundException; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.core.AsyncResult; import io.vertx.core.Future; @@ -5040,4 +5042,38 @@ void clientVersionQueryParameter(String clientVersion, Vertx vertx, VertxTestCon testContext.completeNow(); }); } + + @Test // note that this test will be removed when we switch to logging versions + void clientVersionHeaderNotFound(Vertx vertx, VertxTestContext testContext) { + WebClient client = WebClient.create(vertx); + String clientVersion = "invalid-sdk"; + HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint?client=" + clientVersion)); + req.send(ar -> { + assertEquals(404, ar.result().statusCode()); + assertThrows(MeterNotFoundException.class, () -> { + Counter counter = Metrics.globalRegistry + .get("uid2.client_sdk_versions") + .tag("client_version", clientVersion) + .counter(); + }); + testContext.completeNow(); + }); + } + + @Test // note that this test will be removed when we switch to logging versions + void clientVersionQueryParameterNotFound(Vertx vertx, VertxTestContext testContext) { + WebClient client = WebClient.create(vertx); + String clientVersion = "invalid-sdk"; + HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint?client=" + clientVersion)); + req.send(ar -> { + assertEquals(404, ar.result().statusCode()); + assertThrows(MeterNotFoundException.class, () -> { + Counter counter = Metrics.globalRegistry + .get("uid2.client_sdk_versions") + .tag("client_version", clientVersion) + .counter(); + }); + testContext.completeNow(); + }); + } } From c9ffecddce5645bb7b203bdf32c1fb64138bdfd9 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 29 May 2024 15:24:15 -0600 Subject: [PATCH 0454/1116] client version not found test --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b0c8999f7..c7da23e07 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -5046,8 +5046,9 @@ void clientVersionQueryParameter(String clientVersion, Vertx vertx, VertxTestCon @Test // note that this test will be removed when we switch to logging versions void clientVersionHeaderNotFound(Vertx vertx, VertxTestContext testContext) { WebClient client = WebClient.create(vertx); + HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint")); String clientVersion = "invalid-sdk"; - HttpRequest req = client.getAbs(getUrlForEndpoint("/any/endpoint?client=" + clientVersion)); + req.putHeader("X-UID2-Client-Version", clientVersion); req.send(ar -> { assertEquals(404, ar.result().statusCode()); assertThrows(MeterNotFoundException.class, () -> { From 3f1d95a8e9ab58332acdecc6f48535be45a8ba25 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 29 May 2024 15:25:33 -0600 Subject: [PATCH 0455/1116] client version not found test --- src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index c7da23e07..7be340ef0 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -5052,7 +5052,7 @@ void clientVersionHeaderNotFound(Vertx vertx, VertxTestContext testContext) { req.send(ar -> { assertEquals(404, ar.result().statusCode()); assertThrows(MeterNotFoundException.class, () -> { - Counter counter = Metrics.globalRegistry + Metrics.globalRegistry .get("uid2.client_sdk_versions") .tag("client_version", clientVersion) .counter(); @@ -5069,7 +5069,7 @@ void clientVersionQueryParameterNotFound(Vertx vertx, VertxTestContext testConte req.send(ar -> { assertEquals(404, ar.result().statusCode()); assertThrows(MeterNotFoundException.class, () -> { - Counter counter = Metrics.globalRegistry + Metrics.globalRegistry .get("uid2.client_sdk_versions") .tag("client_version", clientVersion) .counter(); From ae288fba25b24b76936624dcd28711fb67f0be12 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Wed, 29 May 2024 20:34:08 -0700 Subject: [PATCH 0456/1116] Address the comments and add unit tests --- .../TokenResponseStatsCollector.java | 6 +- .../operator/vertx/UIDOperatorVerticle.java | 12 +- .../operator/UIDOperatorVerticleTest.java | 137 ++++++++++++------ 3 files changed, 105 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 3b99586fb..8e0e29744 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -43,9 +43,9 @@ public enum ResponseStatus { } public enum PlatformType { - InApp, - HasOriginHeader, - Other + InApp, // Request containing the "X-UID2-Client-Version" header, typically originating from Android, iOS, or tvOS (Apple TV). + HasOriginHeader, // Request containing the "original" header, originating from the web. + Other // Everything else, such as requests originating from the server side. } public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus, PlatformType platformType) { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 5cdebcd27..975d6f281 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -125,6 +125,10 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final int optOutStatusMaxRequestSize; private final boolean optOutStatusApiEnabled; + //"Android" is from https://github.com/IABTechLab/uid2-android-sdk/blob/ff93ebf597f5de7d440a84f7015a334ba4138ede/sdk/src/main/java/com/uid2/UID2Client.kt#L46 + //"ios"/"tvos" is from https://github.com/IABTechLab/uid2-ios-sdk/blob/91c290d29a7093cfc209eca493d1fee80c17e16a/Sources/UID2/UID2Client.swift#L36-L38 + private final Set SUPPORTED_IN_APP = new HashSet<>(Arrays.asList("Android", "ios", "tvos")); + public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, ISiteStore siteProvider, @@ -327,7 +331,6 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA final JsonObject body; TokenResponseStatsCollector.PlatformType platformType = TokenResponseStatsCollector.PlatformType.Other; try { - platformType = getPlatformType(rc); body = rc.body().asJsonObject(); } catch (DecodeException ex) { SendClientErrorResponseAndRecordStats(ResponseStatus.ClientError, 400, rc, "json payload is not valid", @@ -342,6 +345,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA } final CstgRequest request = body.mapTo(CstgRequest.class); + platformType = request.getAppName() != null ? TokenResponseStatsCollector.PlatformType.InApp : getPlatformType(rc); final ClientSideKeypair clientSideKeypair = this.clientSideKeypairProvider.getSnapshot().getKeypair(request.getSubscriptionId()); if (clientSideKeypair == null) { @@ -1795,7 +1799,7 @@ private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { } public static String getSiteName(ISiteStore siteStore, Integer siteId) { - if (siteId == null) return "X-UID2-Client-Version"; + if (siteId == null) return "unknown"; if (siteStore == null) return "unknown"; //this is expected if CSTG is not enabled, eg for private operators final Site site = siteStore.getSite(siteId); @@ -1803,8 +1807,8 @@ public static String getSiteName(ISiteStore siteStore, Integer siteId) { } private TokenResponseStatsCollector.PlatformType getPlatformType(RoutingContext rc) { - final String clientVersion = rc.request().getHeader("X-UID2-Client-Version"); - if (clientVersion != null && (clientVersion.contains("Android") || clientVersion.contains("ios") || clientVersion.contains("tvos"))) { + final String clientVersionHeader = rc.request().getHeader("X-UID2-Client-Version"); + if (clientVersionHeader != null && (SUPPORTED_IN_APP.stream().anyMatch(clientVersionHeader::contains))) { return TokenResponseStatsCollector.PlatformType.InApp; } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index eb41d8467..ebfb96c87 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -93,6 +93,11 @@ public class UIDOperatorVerticleTest { private static final String clientSideTokenGenerateSubscriptionId = "4WvryDGbR5"; private static final String clientSideTokenGeneratePublicKey = "UID2-X-L-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsziOqRXZ7II0uJusaMxxCxlxgj8el/MUYLFMtWfB71Q3G1juyrAnzyqruNiPPnIuTETfFOridglP9UQNlwzNQg=="; private static final String clientSideTokenGeneratePrivateKey = "UID2-Y-L-MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBop1Dw/IwDcstgicr/3tDoyR3OIpgAWgw8mD6oTO+1ug=="; + private static final String clientVersionHeader = "X-UID2-Client-Version"; + private static final String originHeader = "origin"; + private static final String androidClientVersionHeaderValue = "Android-1.2.3"; + private static final String iosClientVersionHeaderValue = "ios-1.2.3"; + private static final String tvosClientVersionHeaderValue = "tvos-1.2.3"; private static final int clientSideTokenGenerateSiteId = 123; private static final int optOutStatusMaxRequestSize = 1000; @@ -252,6 +257,10 @@ protected void sendTokenGenerate(String apiVersion, Vertx vertx, String v1GetPar } private void sendTokenGenerate(String apiVersion, Vertx vertx, String v1GetParam, JsonObject v2PostPayload, int expectedHttpCode, String referer, Handler handler, boolean additionalParams) { + sendTokenGenerate(apiVersion, vertx, v1GetParam, v2PostPayload, expectedHttpCode, referer, handler, additionalParams, null, null); + } + + private void sendTokenGenerate(String apiVersion, Vertx vertx, String v1GetParam, JsonObject v2PostPayload, int expectedHttpCode, String referer, Handler handler, boolean additionalParams, String headerName, String headerValue) { if (apiVersion.equals("v2")) { ClientKey ck = (ClientKey) clientKeyProvider.get(""); @@ -278,21 +287,30 @@ private void sendTokenGenerate(String apiVersion, Vertx vertx, String v1GetParam } else { handler.handle(tryParseResponse(ar.result())); } - }); + }, headerName, headerValue); } else { get(vertx, apiVersion + "/token/generate" + (v1GetParam != null ? "?" + v1GetParam : ""), ar -> { assertTrue(ar.succeeded()); assertEquals(expectedHttpCode, ar.result().statusCode()); handler.handle(tryParseResponse(ar.result())); - }); + }, headerName, headerValue); } } private void sendTokenRefresh(String apiVersion, Vertx vertx, VertxTestContext testContext, String refreshToken, String v2RefreshDecryptSecret, int expectedHttpCode, Handler handler) { + sendTokenRefresh(apiVersion, vertx, null, null, testContext, refreshToken, v2RefreshDecryptSecret, expectedHttpCode, handler); + } + + private void sendTokenRefresh(String apiVersion, Vertx vertx, String headerName, String headerValue, VertxTestContext testContext, String refreshToken, String v2RefreshDecryptSecret, int expectedHttpCode, + Handler handler) { if (apiVersion.equals("v2")) { WebClient client = WebClient.create(vertx); - client.postAbs(getUrlForEndpoint("v2/token/refresh")) + HttpRequest refreshHttpRequest = client.postAbs(getUrlForEndpoint("v2/token/refresh")); + if (headerName != null) { + refreshHttpRequest.putHeader(headerName, headerValue); + } + refreshHttpRequest .putHeader("content-type", "text/plain") .sendBuffer(Buffer.buffer(refreshToken.getBytes(StandardCharsets.UTF_8)), testContext.succeeding(response -> testContext.verify(() -> { assertEquals(expectedHttpCode, response.statusCode()); @@ -314,7 +332,7 @@ private void sendTokenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertEquals(expectedHttpCode, response.statusCode()); JsonObject json = response.bodyAsJsonObject(); handler.handle(json); - }))); + })), headerName, headerValue); } } @@ -354,6 +372,19 @@ private void get(Vertx vertx, String endpoint, Handler>> handler, String headerName, String headerValue) { + WebClient client = WebClient.create(vertx); + ClientKey ck = clientKeyProvider.getClientKey(""); + HttpRequest req = client.getAbs(getUrlForEndpoint(endpoint)); + if (ck != null) { + req.putHeader("Authorization", "Bearer " + clientKey); + } + if (headerName != null) { + req.putHeader(headerName, headerValue); + } + req.send(handler); + } + private void post(Vertx vertx, String endpoint, JsonObject body, Handler>> handler) { WebClient client = WebClient.create(vertx); ClientKey ck = clientKeyProvider.getClientKey(""); @@ -364,6 +395,9 @@ private void post(Vertx vertx, String endpoint, JsonObject body, Handler>> handler) { + postV2(ck, vertx, endpoint, body, nonce, referer, handler, null, null); + } + private void postV2(ClientKey ck, Vertx vertx, String endpoint, JsonObject body, long nonce, String referer, Handler>> handler, String headerName, String headerValue) { WebClient client = WebClient.create(vertx); Buffer b = Buffer.buffer(); @@ -383,6 +417,10 @@ private void postV2(ClientKey ck, Vertx vertx, String endpoint, JsonObject body, HttpRequest request = client.postAbs(getUrlForEndpoint(endpoint)) .putHeader("Authorization", "Bearer " + apiKey) .putHeader("content-type", "text/plain"); + if (headerName != null) { + request.putHeader(headerName, headerValue); + } + if (referer != null) { request.putHeader("Referer", referer); } @@ -557,11 +595,14 @@ protected void setupSiteKey(int siteId, int keyId, int keysetId) { } private void generateTokens(String apiVersion, Vertx vertx, String inputType, String input, Handler handler) { + generateTokens(apiVersion, vertx, inputType, input, handler, null, null); + } + + private void generateTokens(String apiVersion, Vertx vertx, String inputType, String input, Handler handler, String headerName, String headerValue) { String v1Param = inputType + "=" + urlEncode(input); JsonObject v2Payload = new JsonObject(); v2Payload.put(inputType, input); - - sendTokenGenerate(apiVersion, vertx, v1Param, v2Payload, 200, handler); + sendTokenGenerate(apiVersion, vertx, v1Param, v2Payload, 200, null, handler, true, headerName, headerValue); } private static void assertEqualsClose(Instant expected, Instant actual, int withinSeconds) { @@ -1148,9 +1189,9 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi 201, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.Other); - sendTokenRefresh("v2", vertx, testContext, body.getString("refresh_token"), body.getString("refresh_response_key"), 200, refreshRespJson -> + sendTokenRefresh("v2", vertx, clientVersionHeader, tvosClientVersionHeaderValue, testContext, body.getString("refresh_token"), body.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("optout", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); @@ -1159,7 +1200,7 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi 201, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.OptOut, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.InApp); testContext.completeNow(); }); }); @@ -1265,7 +1306,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - sendTokenRefresh(apiVersion, vertx, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> + sendTokenRefresh(apiVersion, vertx, clientVersionHeader, iosClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); @@ -1293,16 +1334,16 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.GenerateV1 : TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.InApp); assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.InApp); testContext.completeNow(); }); - }); + }, clientVersionHeader, iosClientVersionHeaderValue); } @ParameterizedTest @@ -1324,7 +1365,7 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - sendTokenRefresh(apiVersion, vertx, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> + sendTokenRefresh(apiVersion, vertx, clientVersionHeader, androidClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); @@ -1352,18 +1393,18 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.GenerateV1 : TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.InApp); assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.InApp); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); testContext.completeNow(); }); - }); + }, clientVersionHeader, androidClientVersionHeaderValue); } @Test @@ -1387,7 +1428,7 @@ void tokenGenerateThenRefreshNoActiveKey(Vertx vertx, VertxTestContext testConte String genRefreshToken = bodyJson.getString("refresh_token"); setupKeys(true); - sendTokenRefresh("v2", vertx, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 500, refreshRespJson -> + sendTokenRefresh("v2", vertx, clientVersionHeader, androidClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 500, refreshRespJson -> { assertFalse(refreshRespJson.containsKey("body")); assertEquals("No active encryption key available", refreshRespJson.getString("message")); @@ -1591,13 +1632,13 @@ void tokenGenerateNoActiveKey(Vertx vertx, VertxTestContext testContext) { void tokenRefreshNoToken(String apiVersion, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; fakeAuth(clientSiteId, Role.GENERATOR); - sendTokenRefresh(apiVersion, vertx, testContext, "", "", 400, json -> { + sendTokenRefresh(apiVersion, vertx, null, null, testContext, "", "", 400, json -> { assertEquals("invalid_token", json.getString("status")); assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.InvalidToken, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); }); } @@ -1608,13 +1649,13 @@ void tokenRefreshInvalidTokenAuthenticated(String apiVersion, Vertx vertx, Vertx final int clientSiteId = 201; fakeAuth(clientSiteId, Role.GENERATOR); - sendTokenRefresh(apiVersion, vertx, testContext, "abcd", "", 400, json -> { + sendTokenRefresh(apiVersion, vertx, originHeader, "example.com", testContext, "abcd", "", 400, json -> { assertEquals("invalid_token", json.getString("status")); assertTokenStatusMetrics( clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.InvalidToken, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -1622,7 +1663,7 @@ void tokenRefreshInvalidTokenAuthenticated(String apiVersion, Vertx vertx, Vertx @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenRefreshInvalidTokenUnauthenticated(String apiVersion, Vertx vertx, VertxTestContext testContext) { - sendTokenRefresh(apiVersion, vertx, testContext, "abcd", "", 400, json -> { + sendTokenRefresh(apiVersion, vertx, null, null, testContext, "abcd", "", 400, json -> { assertEquals("error", json.getString("status")); testContext.completeNow(); }); @@ -1743,7 +1784,7 @@ void tokenRefreshOptOut(String apiVersion, Vertx vertx, VertxTestContext testCon clientSiteId, apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.OptOut, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); }); }); @@ -2610,7 +2651,7 @@ void tokenRefreshOptOutForPhone(String apiVersion, Vertx vertx, VertxTestContext assertEquals(200, response.statusCode()); JsonObject json = response.bodyAsJsonObject(); assertEquals("optout", json.getString("status")); - assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.OptOut, TokenResponseStatsCollector.PlatformType.Unknown); + assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.RefreshV1, TokenResponseStatsCollector.ResponseStatus.OptOut, TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); }))); @@ -2902,7 +2943,7 @@ void tokenGenerateRespectOptOutOption(String policyParameterKey, Vertx vertx, Ve try { Assertions.assertEquals(ResponseUtil.ResponseStatus.OptOut, json.getString("status")); Assertions.assertNull(json.getJsonObject("body")); - assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, TokenResponseStatsCollector.PlatformType.Unknown); + assertTokenStatusMetrics(clientSiteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); } catch (Exception e) { testContext.failNow(e); @@ -3029,7 +3070,7 @@ private void postCstg(Vertx vertx, String endpoint, String httpOriginHeader, Jso WebClient client = WebClient.create(vertx); HttpRequest req = client.postAbs(getUrlForEndpoint(endpoint)); if (httpOriginHeader != null) { - req.putHeader("origin", httpOriginHeader); + req.putHeader(originHeader, httpOriginHeader); } req.sendJsonObject(body, handler); } @@ -3084,7 +3125,7 @@ void cstgNoIdentityHashProvided(Vertx vertx, VertxTestContext testContext) throw clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.MissingParams, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3114,7 +3155,7 @@ void cstgDomainNameCheckFails(boolean setOptoutCheckFlagInRequest, String httpOr clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3146,7 +3187,7 @@ void cstgAppNameCheckFails(String appName, Vertx vertx, VertxTestContext testCon clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidAppName, - TokenResponseStatsCollector.PlatformType.Mobile); + TokenResponseStatsCollector.PlatformType.InApp); testContext.completeNow(); }); } @@ -3180,7 +3221,7 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(boolean setOptoutCheckFlagI clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3204,6 +3245,11 @@ void cstgLogsInvalidAppName(String appName, Vertx vertx, VertxTestContext testCo testContext, respJson -> { Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("InvalidHttpOriginAndAppName: site test (123): " + appName)); + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.InvalidAppName, + TokenResponseStatsCollector.PlatformType.InApp); testContext.completeNow(); }); } @@ -3249,7 +3295,7 @@ void cstgDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throw clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unauthorized, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); }); } @@ -3291,7 +3337,7 @@ void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(boolean setOptoutChe clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.InvalidHttpOrigin, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3349,6 +3395,11 @@ void cstgAppNameCheckPasses(String appName, Vertx vertx, VertxTestContext testCo assertNotNull(refreshBody); var encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); validateAndGetToken(encoder, refreshBody, IdentityType.Email); //to validate token version is correct + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.Success, + TokenResponseStatsCollector.PlatformType.InApp); testContext.completeNow(); }); } @@ -3375,7 +3426,7 @@ void cstgForInvalidJsonPayloadReturns400(Vertx vertx, VertxTestContext testConte WebClient client = WebClient.create(vertx); client.postAbs(getUrlForEndpoint("v2/token/client-generate")) - .putHeader("origin", "https://cstg.co.uk") + .putHeader(originHeader, "https://cstg.co.uk") .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer("not a valid json payload"), result -> testContext.verify(() -> { assertEquals(400, result.result().statusCode()); @@ -3468,7 +3519,7 @@ void cstgBadPublicKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAl clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPublicKey, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3555,7 +3606,7 @@ void cstgBadIvNotBase64(Vertx vertx, VertxTestContext testContext) throws NoSuch clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadIV, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3601,7 +3652,7 @@ void cstgBadIvIncorrectLength(Vertx vertx, VertxTestContext testContext) throws clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadIV, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3644,7 +3695,7 @@ void cstgBadEncryptedPayload(Vertx vertx, VertxTestContext testContext) throws N clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3685,7 +3736,7 @@ void cstgInvalidEncryptedPayloadJson(Vertx vertx, VertxTestContext testContext) clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3730,7 +3781,7 @@ void cstgPhoneAndEmailProvided(Vertx vertx, VertxTestContext testContext) throws clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -3776,7 +3827,7 @@ void cstgNoPhoneSupport(Vertx vertx, VertxTestContext testContext) throws NoSuch clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.BadPayload, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); testContext.completeNow(); }); } @@ -4000,7 +4051,7 @@ else if(identityType == IdentityType.Phone) { clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Web); + TokenResponseStatsCollector.PlatformType.HasOriginHeader); String genRefreshToken = genBody.getString("refresh_token"); //test a subsequent refresh from this cstg call and see if it still works @@ -4044,7 +4095,7 @@ else if(identityType == IdentityType.Phone) { clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.RefreshV2, TokenResponseStatsCollector.ResponseStatus.Success, - TokenResponseStatsCollector.PlatformType.Unknown); + TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); }); From 83ea8bdc13e4df315d2f8534b6f2cdc9629ef28e Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Thu, 30 May 2024 18:19:15 -0700 Subject: [PATCH 0457/1116] Address the comments --- .../monitoring/TokenResponseStatsCollector.java | 4 ++-- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 8e0e29744..95d0aad1d 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -43,8 +43,8 @@ public enum ResponseStatus { } public enum PlatformType { - InApp, // Request containing the "X-UID2-Client-Version" header, typically originating from Android, iOS, or tvOS (Apple TV). - HasOriginHeader, // Request containing the "original" header, originating from the web. + InApp, // Request has the "X-UID2-Client-Version" header, which contains "Android", "ios" or "tvos", typically originating from Android, iOS, or tvOS (Apple TV). + HasOriginHeader, // Request has the "origin" header, originating from the web. Other // Everything else, such as requests originating from the server side. } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 975d6f281..ba6b78856 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -127,7 +127,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { //"Android" is from https://github.com/IABTechLab/uid2-android-sdk/blob/ff93ebf597f5de7d440a84f7015a334ba4138ede/sdk/src/main/java/com/uid2/UID2Client.kt#L46 //"ios"/"tvos" is from https://github.com/IABTechLab/uid2-ios-sdk/blob/91c290d29a7093cfc209eca493d1fee80c17e16a/Sources/UID2/UID2Client.swift#L36-L38 - private final Set SUPPORTED_IN_APP = new HashSet<>(Arrays.asList("Android", "ios", "tvos")); + private final static List SUPPORTED_IN_APP = Arrays.asList("Android", "ios", "tvos"); public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, @@ -1807,9 +1807,13 @@ public static String getSiteName(ISiteStore siteStore, Integer siteId) { } private TokenResponseStatsCollector.PlatformType getPlatformType(RoutingContext rc) { - final String clientVersionHeader = rc.request().getHeader("X-UID2-Client-Version"); - if (clientVersionHeader != null && (SUPPORTED_IN_APP.stream().anyMatch(clientVersionHeader::contains))) { - return TokenResponseStatsCollector.PlatformType.InApp; + final String clientVersionHeader = rc.request().getHeader(Const.Http.ClientVersionHeader); + if (clientVersionHeader != null) { + for (String supportedVersion : SUPPORTED_IN_APP) { + if (clientVersionHeader.contains(supportedVersion)) { + return TokenResponseStatsCollector.PlatformType.InApp; + } + } } final String origin = rc.request().getHeader("origin"); From 09def0f0b3a5b9f362f9c16b734856ae7f68aa29 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Thu, 30 May 2024 18:51:11 -0700 Subject: [PATCH 0458/1116] Remove one more magic word --- .../monitoring/TokenResponseStatsCollector.java | 2 +- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 11 ++++++----- .../com/uid2/operator/UIDOperatorVerticleTest.java | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 95d0aad1d..30c4ffcee 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -44,7 +44,7 @@ public enum ResponseStatus { public enum PlatformType { InApp, // Request has the "X-UID2-Client-Version" header, which contains "Android", "ios" or "tvos", typically originating from Android, iOS, or tvOS (Apple TV). - HasOriginHeader, // Request has the "origin" header, originating from the web. + HasOriginHeader, // Request has the "Origin" header, originating from the web. Other // Everything else, such as requests originating from the server side. } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index ba6b78856..7098d89be 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -128,6 +128,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { //"Android" is from https://github.com/IABTechLab/uid2-android-sdk/blob/ff93ebf597f5de7d440a84f7015a334ba4138ede/sdk/src/main/java/com/uid2/UID2Client.kt#L46 //"ios"/"tvos" is from https://github.com/IABTechLab/uid2-ios-sdk/blob/91c290d29a7093cfc209eca493d1fee80c17e16a/Sources/UID2/UID2Client.swift#L36-L38 private final static List SUPPORTED_IN_APP = Arrays.asList("Android", "ios", "tvos"); + private final static String ORIGIN_HEADER = "Origin"; public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, @@ -524,7 +525,7 @@ private OriginOrAppNameValidationResult validateOriginOrAppName(RoutingContext r : OriginOrAppNameValidationResult.invalidAppName(appName); } - final String origin = rc.request().getHeader("origin"); + final String origin = rc.request().getHeader(ORIGIN_HEADER); final Set domainNames = getDomainNameListForClientSideTokenGenerate(keypair); return origin != null && DomainNameCheckUtil.isDomainNameAllowed(origin, domainNames) @@ -848,7 +849,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { } } else { ResponseUtil.Success(rc, toJsonV1(r.getTokens())); - this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains("Origin")); + this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV1, r, platformType); @@ -882,7 +883,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { } } else { ResponseUtil.SuccessV2(rc, toJsonV1(r.getTokens())); - this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains("Origin")); + this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r, platformType); } catch (Exception e) { @@ -1102,7 +1103,7 @@ private void handleTokenRefresh(RoutingContext rc) { siteId = rc.get(Const.RoutingContextData.SiteId); if (r.isRefreshed()) { - this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains("Origin")); + this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV0, r, TokenResponseStatsCollector.PlatformType.Other); } catch (Exception e) { @@ -1816,7 +1817,7 @@ private TokenResponseStatsCollector.PlatformType getPlatformType(RoutingContext } } - final String origin = rc.request().getHeader("origin"); + final String origin = rc.request().getHeader(ORIGIN_HEADER); return origin != null ? TokenResponseStatsCollector.PlatformType.HasOriginHeader : TokenResponseStatsCollector.PlatformType.Other; } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index ebfb96c87..44b79e9f2 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -94,7 +94,7 @@ public class UIDOperatorVerticleTest { private static final String clientSideTokenGeneratePublicKey = "UID2-X-L-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsziOqRXZ7II0uJusaMxxCxlxgj8el/MUYLFMtWfB71Q3G1juyrAnzyqruNiPPnIuTETfFOridglP9UQNlwzNQg=="; private static final String clientSideTokenGeneratePrivateKey = "UID2-Y-L-MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBop1Dw/IwDcstgicr/3tDoyR3OIpgAWgw8mD6oTO+1ug=="; private static final String clientVersionHeader = "X-UID2-Client-Version"; - private static final String originHeader = "origin"; + private static final String originHeader = "Origin"; private static final String androidClientVersionHeaderValue = "Android-1.2.3"; private static final String iosClientVersionHeaderValue = "ios-1.2.3"; private static final String tvosClientVersionHeaderValue = "tvos-1.2.3"; From 454e554889f8fe69f2e97f3528f449f805d77513 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Thu, 30 May 2024 19:07:36 -0700 Subject: [PATCH 0459/1116] Remove extra code --- .../operator/vertx/UIDOperatorVerticle.java | 2 +- .../operator/UIDOperatorVerticleTest.java | 24 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 7098d89be..44635be26 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -128,7 +128,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { //"Android" is from https://github.com/IABTechLab/uid2-android-sdk/blob/ff93ebf597f5de7d440a84f7015a334ba4138ede/sdk/src/main/java/com/uid2/UID2Client.kt#L46 //"ios"/"tvos" is from https://github.com/IABTechLab/uid2-ios-sdk/blob/91c290d29a7093cfc209eca493d1fee80c17e16a/Sources/UID2/UID2Client.swift#L36-L38 private final static List SUPPORTED_IN_APP = Arrays.asList("Android", "ios", "tvos"); - private final static String ORIGIN_HEADER = "Origin"; + public final static String ORIGIN_HEADER = "Origin"; public UIDOperatorVerticle(JsonObject config, boolean clientSideTokenGenerate, diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 44b79e9f2..d7092ac94 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -70,9 +70,9 @@ import static com.uid2.operator.ClientSideTokenGenerateTestUtil.decrypt; import static com.uid2.operator.IdentityConst.*; import static com.uid2.operator.service.EncodingUtils.getSha256; -import static com.uid2.operator.vertx.UIDOperatorVerticle.OPT_OUT_CHECK_CUTOFF_DATE; -import static com.uid2.operator.vertx.UIDOperatorVerticle.TOKEN_LIFETIME_TOLERANCE; +import static com.uid2.operator.vertx.UIDOperatorVerticle.*; import static com.uid2.shared.Const.Data.*; +import static com.uid2.shared.Const.Http.ClientVersionHeader; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -93,8 +93,6 @@ public class UIDOperatorVerticleTest { private static final String clientSideTokenGenerateSubscriptionId = "4WvryDGbR5"; private static final String clientSideTokenGeneratePublicKey = "UID2-X-L-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsziOqRXZ7II0uJusaMxxCxlxgj8el/MUYLFMtWfB71Q3G1juyrAnzyqruNiPPnIuTETfFOridglP9UQNlwzNQg=="; private static final String clientSideTokenGeneratePrivateKey = "UID2-Y-L-MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBop1Dw/IwDcstgicr/3tDoyR3OIpgAWgw8mD6oTO+1ug=="; - private static final String clientVersionHeader = "X-UID2-Client-Version"; - private static final String originHeader = "Origin"; private static final String androidClientVersionHeaderValue = "Android-1.2.3"; private static final String iosClientVersionHeaderValue = "ios-1.2.3"; private static final String tvosClientVersionHeaderValue = "tvos-1.2.3"; @@ -1191,7 +1189,7 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi TokenResponseStatsCollector.ResponseStatus.Success, TokenResponseStatsCollector.PlatformType.Other); - sendTokenRefresh("v2", vertx, clientVersionHeader, tvosClientVersionHeaderValue, testContext, body.getString("refresh_token"), body.getString("refresh_response_key"), 200, refreshRespJson -> + sendTokenRefresh("v2", vertx, ClientVersionHeader, tvosClientVersionHeaderValue, testContext, body.getString("refresh_token"), body.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("optout", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); @@ -1306,7 +1304,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - sendTokenRefresh(apiVersion, vertx, clientVersionHeader, iosClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> + sendTokenRefresh(apiVersion, vertx, ClientVersionHeader, iosClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); @@ -1343,7 +1341,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t testContext.completeNow(); }); - }, clientVersionHeader, iosClientVersionHeaderValue); + }, ClientVersionHeader, iosClientVersionHeaderValue); } @ParameterizedTest @@ -1365,7 +1363,7 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - sendTokenRefresh(apiVersion, vertx, clientVersionHeader, androidClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> + sendTokenRefresh(apiVersion, vertx, ClientVersionHeader, androidClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); @@ -1404,7 +1402,7 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT testContext.completeNow(); }); - }, clientVersionHeader, androidClientVersionHeaderValue); + }, ClientVersionHeader, androidClientVersionHeaderValue); } @Test @@ -1428,7 +1426,7 @@ void tokenGenerateThenRefreshNoActiveKey(Vertx vertx, VertxTestContext testConte String genRefreshToken = bodyJson.getString("refresh_token"); setupKeys(true); - sendTokenRefresh("v2", vertx, clientVersionHeader, androidClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 500, refreshRespJson -> + sendTokenRefresh("v2", vertx, ClientVersionHeader, androidClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 500, refreshRespJson -> { assertFalse(refreshRespJson.containsKey("body")); assertEquals("No active encryption key available", refreshRespJson.getString("message")); @@ -1649,7 +1647,7 @@ void tokenRefreshInvalidTokenAuthenticated(String apiVersion, Vertx vertx, Vertx final int clientSiteId = 201; fakeAuth(clientSiteId, Role.GENERATOR); - sendTokenRefresh(apiVersion, vertx, originHeader, "example.com", testContext, "abcd", "", 400, json -> { + sendTokenRefresh(apiVersion, vertx, ORIGIN_HEADER, "example.com", testContext, "abcd", "", 400, json -> { assertEquals("invalid_token", json.getString("status")); assertTokenStatusMetrics( clientSiteId, @@ -3070,7 +3068,7 @@ private void postCstg(Vertx vertx, String endpoint, String httpOriginHeader, Jso WebClient client = WebClient.create(vertx); HttpRequest req = client.postAbs(getUrlForEndpoint(endpoint)); if (httpOriginHeader != null) { - req.putHeader(originHeader, httpOriginHeader); + req.putHeader(ORIGIN_HEADER, httpOriginHeader); } req.sendJsonObject(body, handler); } @@ -3426,7 +3424,7 @@ void cstgForInvalidJsonPayloadReturns400(Vertx vertx, VertxTestContext testConte WebClient client = WebClient.create(vertx); client.postAbs(getUrlForEndpoint("v2/token/client-generate")) - .putHeader(originHeader, "https://cstg.co.uk") + .putHeader(ORIGIN_HEADER, "https://cstg.co.uk") .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer("not a valid json payload"), result -> testContext.verify(() -> { assertEquals(400, result.result().statusCode()); From 9a18674d14e1110279c89640a97ce3968db1d997 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 31 May 2024 15:07:09 +0000 Subject: [PATCH 0460/1116] [CI Pipeline] Released Patch version: 5.34.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b7f73794..894ae7103 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.34.4 + 5.34.12 UTF-8 From 2d3dfc7addd87777c7ca89791056fb79fb2584a2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 31 May 2024 20:45:00 +0000 Subject: [PATCH 0461/1116] [CI Pipeline] Released Minor version: 5.35.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 894ae7103..ba816e4ae 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.34.12 + 5.35.0 UTF-8 diff --git a/version.json b/version.json index e84dc69db..36747fb28 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.34", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.35", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From 9eea29749e98765bf061fe1226c9e2bab71e7886 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Sun, 2 Jun 2024 21:10:16 -0700 Subject: [PATCH 0462/1116] Allow sending only v4 tokens to a specified list --- .../operator/service/UIDOperatorService.java | 30 +++++++- .../uid2/operator/UIDOperatorServiceTest.java | 77 ++++++++++++++++--- 2 files changed, 95 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 642b3d130..5ff9f068f 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -49,6 +49,7 @@ public class UIDOperatorService implements IUIDOperatorService { private final OperatorIdentity operatorIdentity; private final TokenVersion tokenVersionToUseIfNotV4; private final int advertisingTokenV4Percentage; + private final Set siteIdsUsingV4Tokens; private final TokenVersion refreshTokenVersion; private final boolean identityV3Enabled; @@ -93,6 +94,7 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv } this.advertisingTokenV4Percentage = config.getInteger("advertising_token_v4_percentage", 0); //0 indicates token v4 will not be used + this.siteIdsUsingV4Tokens = getSiteIdsUsingV4Tokens(config.getString("site_ids_using_v4_tokens", "")); this.tokenVersionToUseIfNotV4 = config.getBoolean("advertising_token_v3", false) ? TokenVersion.V3 : TokenVersion.V2; this.refreshTokenVersion = TokenVersion.V3; @@ -311,11 +313,30 @@ private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdent int hash = ((rawUid[0] & 0xFF) << 12) | ((rawUid[1] & 0xFF) << 4) | ((rawUid[2] & 0xFF) & 0xF); //using same logic as ModBasedSaltEntryIndexer.getIndex() in uid2-shared pseudoRandomNumber = (hash % 100) + 1; //1 to 100 } - - var tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; + var tokenVersion = TokenVersion.V4;; + if (!siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { + tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; + } return new AdvertisingToken(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, userIdentity); } + private Set getSiteIdsUsingV4Tokens(String siteIdsUsingV4TokensInString) { + String[] siteIdsV4TokensList = siteIdsUsingV4TokensInString.split(","); + + Set siteIdsV4TokensSet = new HashSet<>(); + try { + for (String siteId : siteIdsV4TokensList) { + String siteIdTrimmed = siteId.trim(); + if (!siteIdTrimmed.isEmpty()) { + siteIdsV4TokensSet.add(Integer.parseInt(siteIdTrimmed)); + } + } + } catch (NumberFormatException ex) { + throw new IllegalArgumentException(String.format("Invalid integer format found in site_ids_using_v4_tokens: %s", siteIdsUsingV4TokensInString)); + } + return siteIdsV4TokensSet; + } + static protected class GlobalOptoutResult { private final boolean isOptedOut; //can be null if isOptedOut is false! @@ -350,8 +371,11 @@ private GlobalOptoutResult getGlobalOptOutResult(UserIdentity userIdentity, bool return new GlobalOptoutResult(result); } - public TokenVersion getAdvertisingTokenVersionForTests() { + public TokenVersion getAdvertisingTokenVersionForTests(int siteId) { assert this.advertisingTokenV4Percentage == 0 || this.advertisingTokenV4Percentage == 100; //we want tests to be deterministic + if (this.siteIdsUsingV4Tokens.contains(siteId)) { + return TokenVersion.V4; + } return this.advertisingTokenV4Percentage == 100 ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 50048283a..8597760da 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -80,6 +80,7 @@ void setup() throws Exception { uid2Config.put(UIDOperatorService.REFRESH_TOKEN_EXPIRES_AFTER_SECONDS, REFRESH_TOKEN_EXPIRES_AFTER_SECONDS); uid2Config.put(UIDOperatorService.REFRESH_IDENTITY_TOKEN_AFTER_SECONDS, REFRESH_IDENTITY_TOKEN_AFTER_SECONDS); uid2Config.put("advertising_token_v4_percentage", 0); + uid2Config.put("site_ids_using_v4_tokens", "127,128"); uid2Config.put("advertising_token_v3", false); // prod is using v2 token version for now uid2Config.put("identity_v3", false); @@ -98,6 +99,7 @@ void setup() throws Exception { euidConfig.put(UIDOperatorService.REFRESH_TOKEN_EXPIRES_AFTER_SECONDS, REFRESH_TOKEN_EXPIRES_AFTER_SECONDS); euidConfig.put(UIDOperatorService.REFRESH_IDENTITY_TOKEN_AFTER_SECONDS, REFRESH_IDENTITY_TOKEN_AFTER_SECONDS); euidConfig.put("advertising_token_v4_percentage", 0); + euidConfig.put("site_ids_using_v4_tokens", ""); euidConfig.put("advertising_token_v3", true); euidConfig.put("identity_v3", true); @@ -133,8 +135,8 @@ private UserIdentity createUserIdentity(String rawIdentityHash, IdentityScope sc ); } - private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type) { - TokenVersion tokenVersion = (scope == IdentityScope.UID2) ? uid2Service.getAdvertisingTokenVersionForTests() : euidService.getAdvertisingTokenVersionForTests(); + private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type, int siteId) { + TokenVersion tokenVersion = (scope == IdentityScope.UID2) ? uid2Service.getAdvertisingTokenVersionForTests(siteId) : euidService.getAdvertisingTokenVersionForTests(siteId); UIDOperatorVerticleTest.validateAdvertisingToken(advertisingTokenString, tokenVersion, scope, type); return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } @@ -151,7 +153,7 @@ public void testGenerateAndRefresh() { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); - AdvertisingToken advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email, identityRequest.publisherIdentity.siteId); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); assertEquals(identityRequest.userIdentity.identityScope, advertisingToken.userIdentity.identityScope); @@ -176,7 +178,64 @@ public void testGenerateAndRefresh() { assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); assertNotNull(refreshResponse.getTokens()); - AdvertisingToken advertisingToken2 = validateAndGetToken(tokenEncoder, refreshResponse.getTokens().getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken2 = validateAndGetToken(tokenEncoder, refreshResponse.getTokens().getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email, identityRequest.publisherIdentity.siteId); + assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); + assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); + assertEquals(advertisingToken.userIdentity.identityScope, advertisingToken2.userIdentity.identityScope); + assertEquals(advertisingToken.userIdentity.identityType, advertisingToken2.userIdentity.identityType); + assertEquals(advertisingToken.userIdentity.establishedAt, advertisingToken2.userIdentity.establishedAt); + assertArrayEquals(advertisingToken.userIdentity.id, advertisingToken2.userIdentity.id); + + RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getTokens().getRefreshToken()); + assertEquals(this.now, refreshToken2.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken2.expiresAt); + assertEquals(refreshToken.publisherIdentity.siteId, refreshToken2.publisherIdentity.siteId); + assertEquals(refreshToken.userIdentity.identityScope, refreshToken2.userIdentity.identityScope); + assertEquals(refreshToken.userIdentity.identityType, refreshToken2.userIdentity.identityType); + assertEquals(refreshToken.userIdentity.establishedAt, refreshToken2.userIdentity.establishedAt); + assertArrayEquals(refreshToken.userIdentity.id, refreshToken2.userIdentity.id); + } + + @Test + public void testGenerateAndRefreshForSiteIdUsingV4Token() { + final IdentityRequest identityRequest = new IdentityRequest( + new PublisherIdentity(127, 124, 125), + createUserIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), + OptoutCheckPolicy.DoNotRespect + ); + final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); + assertNotNull(tokens); + + UIDOperatorVerticleTest.validateAdvertisingToken(tokens.getAdvertisingToken(), TokenVersion.V4, IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(tokens.getAdvertisingToken()); + assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); + assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); + assertEquals(identityRequest.userIdentity.identityScope, advertisingToken.userIdentity.identityScope); + assertEquals(identityRequest.userIdentity.identityType, advertisingToken.userIdentity.identityType); + assertEquals(identityRequest.userIdentity.establishedAt, advertisingToken.userIdentity.establishedAt); + + RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + assertEquals(this.now, refreshToken.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken.expiresAt); + assertEquals(identityRequest.publisherIdentity.siteId, refreshToken.publisherIdentity.siteId); + assertEquals(identityRequest.userIdentity.identityScope, refreshToken.userIdentity.identityScope); + assertEquals(identityRequest.userIdentity.identityType, refreshToken.userIdentity.identityType); + assertEquals(identityRequest.userIdentity.establishedAt, refreshToken.userIdentity.establishedAt); + + setNow(Instant.now().plusSeconds(200)); + + reset(shutdownHandler); + final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshToken); + verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); + verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); + assertNotNull(refreshResponse); + assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); + assertNotNull(refreshResponse.getTokens()); + + UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken(), TokenVersion.V4, IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); assertEquals(advertisingToken.userIdentity.identityScope, advertisingToken2.userIdentity.identityScope); @@ -262,7 +321,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String identity, I tokens = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, userIdentity.identityType); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); tokensAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); @@ -270,7 +329,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String identity, I tokens = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, userIdentity.identityType); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); tokensAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } @@ -569,7 +628,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, else { tokens = uid2Service.generateIdentity(identityRequest); } - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); @@ -691,11 +750,11 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String reset(shutdownHandler); if(scope == IdentityScope.EUID) { tokens = euidService.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, identityRequest.userIdentity.identityType); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); } else { tokens = uid2Service.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, identityRequest.userIdentity.identityType); + advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); From dc7462f327419f8ed5c335129aa7e83778891841 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Sun, 2 Jun 2024 21:49:46 -0700 Subject: [PATCH 0463/1116] Add config --- conf/local-config.json | 1 + scripts/aws/conf/default-config.json | 3 ++- scripts/azure-cc/conf/default-config.json | 3 ++- scripts/gcp-oidc/conf/default-config.json | 3 ++- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 1 - src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java | 1 + 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/conf/local-config.json b/conf/local-config.json index a2146e9bc..309bd00b3 100644 --- a/conf/local-config.json +++ b/conf/local-config.json @@ -14,6 +14,7 @@ "refresh_identity_token_after_seconds": 900, "advertising_token_v3": false, "advertising_token_v4_percentage": 0, + "site_ids_using_v4_tokens": "", "refresh_token_v3": false, "identity_v3": false, "identity_scope": "uid2", diff --git a/scripts/aws/conf/default-config.json b/scripts/aws/conf/default-config.json index 4146e55c0..08860ff3e 100644 --- a/scripts/aws/conf/default-config.json +++ b/scripts/aws/conf/default-config.json @@ -34,5 +34,6 @@ "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, "validate_service_links": false, - "advertising_token_v4_percentage": 0 + "advertising_token_v4_percentage": 0, + "site_ids_using_v4_tokens": "" } diff --git a/scripts/azure-cc/conf/default-config.json b/scripts/azure-cc/conf/default-config.json index c0684b85f..e701e11fd 100644 --- a/scripts/azure-cc/conf/default-config.json +++ b/scripts/azure-cc/conf/default-config.json @@ -38,5 +38,6 @@ "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, "validate_service_links": false, - "advertising_token_v4_percentage": 0 + "advertising_token_v4_percentage": 0, + "site_ids_using_v4_tokens": "" } diff --git a/scripts/gcp-oidc/conf/default-config.json b/scripts/gcp-oidc/conf/default-config.json index c744175a2..3f911c0c8 100644 --- a/scripts/gcp-oidc/conf/default-config.json +++ b/scripts/gcp-oidc/conf/default-config.json @@ -38,5 +38,6 @@ "failure_shutdown_wait_hours": 120, "sharing_token_expiry_seconds": 2592000, "validate_service_links": false, - "advertising_token_v4_percentage": 0 + "advertising_token_v4_percentage": 0, + "site_ids_using_v4_tokens": "" } diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 8597760da..eb8d46de8 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -99,7 +99,6 @@ void setup() throws Exception { euidConfig.put(UIDOperatorService.REFRESH_TOKEN_EXPIRES_AFTER_SECONDS, REFRESH_TOKEN_EXPIRES_AFTER_SECONDS); euidConfig.put(UIDOperatorService.REFRESH_IDENTITY_TOKEN_AFTER_SECONDS, REFRESH_IDENTITY_TOKEN_AFTER_SECONDS); euidConfig.put("advertising_token_v4_percentage", 0); - euidConfig.put("site_ids_using_v4_tokens", ""); euidConfig.put("advertising_token_v3", true); euidConfig.put("identity_v3", true); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 00af05bbf..7a0a8ea1f 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -159,6 +159,7 @@ private void setupConfig(JsonObject config) { config.put("identity_scope", getIdentityScope().toString()); config.put("advertising_token_v3", getTokenVersion() == TokenVersion.V3); config.put("advertising_token_v4_percentage", getTokenVersion() == TokenVersion.V4 ? 100 : 0); + config.put("site_ids_using_v4_tokens", ""); config.put("identity_v3", useIdentityV3()); config.put("client_side_token_generate", true); config.put("key_sharing_endpoint_provide_app_names", true); From 59868d2bb5d4869e3d10dbff49663c40eb359637 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Sun, 2 Jun 2024 21:56:33 -0700 Subject: [PATCH 0464/1116] Remove one typo --- .../java/com/uid2/operator/service/UIDOperatorService.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 5ff9f068f..28996bd25 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -1,5 +1,6 @@ package com.uid2.operator.service; +import ch.qos.logback.core.subst.Token; import com.uid2.operator.model.*; import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.vertx.OperatorShutdownHandler; @@ -313,8 +314,10 @@ private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdent int hash = ((rawUid[0] & 0xFF) << 12) | ((rawUid[1] & 0xFF) << 4) | ((rawUid[2] & 0xFF) & 0xF); //using same logic as ModBasedSaltEntryIndexer.getIndex() in uid2-shared pseudoRandomNumber = (hash % 100) + 1; //1 to 100 } - var tokenVersion = TokenVersion.V4;; - if (!siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { + TokenVersion tokenVersion; + if (siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { + tokenVersion = TokenVersion.V4; + } else { tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } return new AdvertisingToken(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, userIdentity); From d1098d307548b0b7f204f5582c935a55336b5c67 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Sun, 2 Jun 2024 21:58:50 -0700 Subject: [PATCH 0465/1116] Remove unused import --- src/main/java/com/uid2/operator/service/UIDOperatorService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 28996bd25..23b63210c 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -1,6 +1,5 @@ package com.uid2.operator.service; -import ch.qos.logback.core.subst.Token; import com.uid2.operator.model.*; import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.vertx.OperatorShutdownHandler; From 07f88ad11053db6e0e077c3c483ceb25da33304f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 4 Jun 2024 00:06:38 +0000 Subject: [PATCH 0466/1116] [CI Pipeline] Released Minor version: 5.36.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ba816e4ae..97c7d32d3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.35.0 + 5.36.0 UTF-8 diff --git a/version.json b/version.json index 36747fb28..635f245e5 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.35", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.36", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From c7ba5e1f96254c2f1bc83d72cd3acc0221eaec43 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Mon, 3 Jun 2024 18:52:31 -0700 Subject: [PATCH 0467/1116] Address the comments --- .../TokenResponseStatsCollector.java | 2 +- .../com/uid2/operator/service/TokenUtils.java | 20 ++++++ .../operator/service/UIDOperatorService.java | 32 +++------ .../uid2/operator/UIDOperatorServiceTest.java | 69 ++----------------- .../operator/UIDOperatorVerticleTest.java | 2 +- .../uid2/operator/service/TokenUtilsTest.java | 46 +++++++++++++ 6 files changed, 83 insertions(+), 88 deletions(-) create mode 100644 src/test/java/com/uid2/operator/service/TokenUtilsTest.java diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 30c4ffcee..a61446aa9 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -64,7 +64,7 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin "token_response_status", String.valueOf(responseStatus), "advertising_token_version", String.valueOf(advertisingTokenVersion), "cstg", isCstg ? "true" : "false", - "platformType", String.valueOf(platformType)); + "platform_type", String.valueOf(platformType)); builder.register(Metrics.globalRegistry).increment(); } diff --git a/src/main/java/com/uid2/operator/service/TokenUtils.java b/src/main/java/com/uid2/operator/service/TokenUtils.java index dd30b5f8b..4a13145c6 100644 --- a/src/main/java/com/uid2/operator/service/TokenUtils.java +++ b/src/main/java/com/uid2/operator/service/TokenUtils.java @@ -3,6 +3,9 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.IdentityType; +import java.util.HashSet; +import java.util.Set; + public class TokenUtils { public static byte[] getIdentityHash(String identityString) { return EncodingUtils.getSha256Bytes(identityString); @@ -59,4 +62,21 @@ public static byte encodeIdentityScope(IdentityScope identityScope) { public static byte encodeIdentityType(IdentityType identityType) { return (byte) (identityType.value << 2); } + + public static Set getSiteIdsUsingV4Tokens(String siteIdsUsingV4TokensInString) { + String[] siteIdsV4TokensList = siteIdsUsingV4TokensInString.split(","); + + Set siteIdsV4TokensSet = new HashSet<>(); + try { + for (String siteId : siteIdsV4TokensList) { + String siteIdTrimmed = siteId.trim(); + if (!siteIdTrimmed.isEmpty()) { + siteIdsV4TokensSet.add(Integer.parseInt(siteIdTrimmed)); + } + } + } catch (NumberFormatException ex) { + throw new IllegalArgumentException(String.format("Invalid integer format found in site_ids_using_v4_tokens: %s", siteIdsUsingV4TokensInString)); + } + return siteIdsV4TokensSet; + } } diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 23b63210c..02e081092 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -23,6 +23,7 @@ import java.util.*; import static com.uid2.operator.IdentityConst.*; +import static com.uid2.operator.service.TokenUtils.getSiteIdsUsingV4Tokens; public class UIDOperatorService implements IUIDOperatorService { public static final String IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS = "identity_token_expires_after_seconds"; @@ -306,39 +307,22 @@ private RefreshToken createRefreshToken(PublisherIdentity publisherIdentity, Use } private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdentity, UserIdentity userIdentity, Instant now) { - int pseudoRandomNumber = 1; - final var rawUid = userIdentity.id; - if (rawUid.length > 2) - { - int hash = ((rawUid[0] & 0xFF) << 12) | ((rawUid[1] & 0xFF) << 4) | ((rawUid[2] & 0xFF) & 0xF); //using same logic as ModBasedSaltEntryIndexer.getIndex() in uid2-shared - pseudoRandomNumber = (hash % 100) + 1; //1 to 100 - } TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { tokenVersion = TokenVersion.V4; } else { + int pseudoRandomNumber = 1; + final var rawUid = userIdentity.id; + if (rawUid.length > 2) + { + int hash = ((rawUid[0] & 0xFF) << 12) | ((rawUid[1] & 0xFF) << 4) | ((rawUid[2] & 0xFF) & 0xF); //using same logic as ModBasedSaltEntryIndexer.getIndex() in uid2-shared + pseudoRandomNumber = (hash % 100) + 1; //1 to 100 + } tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } return new AdvertisingToken(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, userIdentity); } - private Set getSiteIdsUsingV4Tokens(String siteIdsUsingV4TokensInString) { - String[] siteIdsV4TokensList = siteIdsUsingV4TokensInString.split(","); - - Set siteIdsV4TokensSet = new HashSet<>(); - try { - for (String siteId : siteIdsV4TokensList) { - String siteIdTrimmed = siteId.trim(); - if (!siteIdTrimmed.isEmpty()) { - siteIdsV4TokensSet.add(Integer.parseInt(siteIdTrimmed)); - } - } - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Invalid integer format found in site_ids_using_v4_tokens: %s", siteIdsUsingV4TokensInString)); - } - return siteIdsV4TokensSet; - } - static protected class GlobalOptoutResult { private final boolean isOptedOut; //can be null if isOptedOut is false! diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index eb8d46de8..e175b0e70 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -140,65 +140,11 @@ private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder tokenEncoder, return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } - @Test - public void testGenerateAndRefresh() { - final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), - createUserIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), - OptoutCheckPolicy.DoNotRespect - ); - final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); - verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); - verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); - - AdvertisingToken advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email, identityRequest.publisherIdentity.siteId); - assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); - assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); - assertEquals(identityRequest.userIdentity.identityScope, advertisingToken.userIdentity.identityScope); - assertEquals(identityRequest.userIdentity.identityType, advertisingToken.userIdentity.identityType); - assertEquals(identityRequest.userIdentity.establishedAt, advertisingToken.userIdentity.establishedAt); - - RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); - assertEquals(this.now, refreshToken.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken.expiresAt); - assertEquals(identityRequest.publisherIdentity.siteId, refreshToken.publisherIdentity.siteId); - assertEquals(identityRequest.userIdentity.identityScope, refreshToken.userIdentity.identityScope); - assertEquals(identityRequest.userIdentity.identityType, refreshToken.userIdentity.identityType); - assertEquals(identityRequest.userIdentity.establishedAt, refreshToken.userIdentity.establishedAt); - - setNow(Instant.now().plusSeconds(200)); - - reset(shutdownHandler); - final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshToken); - verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); - verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(refreshResponse); - assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); - assertNotNull(refreshResponse.getTokens()); - - AdvertisingToken advertisingToken2 = validateAndGetToken(tokenEncoder, refreshResponse.getTokens().getAdvertisingToken(), IdentityScope.UID2, IdentityType.Email, identityRequest.publisherIdentity.siteId); - assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); - assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); - assertEquals(advertisingToken.userIdentity.identityScope, advertisingToken2.userIdentity.identityScope); - assertEquals(advertisingToken.userIdentity.identityType, advertisingToken2.userIdentity.identityType); - assertEquals(advertisingToken.userIdentity.establishedAt, advertisingToken2.userIdentity.establishedAt); - assertArrayEquals(advertisingToken.userIdentity.id, advertisingToken2.userIdentity.id); - - RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getTokens().getRefreshToken()); - assertEquals(this.now, refreshToken2.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken2.expiresAt); - assertEquals(refreshToken.publisherIdentity.siteId, refreshToken2.publisherIdentity.siteId); - assertEquals(refreshToken.userIdentity.identityScope, refreshToken2.userIdentity.identityScope); - assertEquals(refreshToken.userIdentity.identityType, refreshToken2.userIdentity.identityType); - assertEquals(refreshToken.userIdentity.establishedAt, refreshToken2.userIdentity.establishedAt); - assertArrayEquals(refreshToken.userIdentity.id, refreshToken2.userIdentity.id); - } - - @Test - public void testGenerateAndRefreshForSiteIdUsingV4Token() { + @ParameterizedTest + @CsvSource({"123, V2","127, V4","128, V4"}) //site id 127 and 128 is for testing "site_ids_using_v4_tokens" + public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(127, 124, 125), + new PublisherIdentity(siteId, 124, 125), createUserIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), OptoutCheckPolicy.DoNotRespect ); @@ -207,9 +153,8 @@ public void testGenerateAndRefreshForSiteIdUsingV4Token() { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokens); - UIDOperatorVerticleTest.validateAdvertisingToken(tokens.getAdvertisingToken(), TokenVersion.V4, IdentityScope.UID2, IdentityType.Email); - AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(tokens.getAdvertisingToken()); - assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); + UIDOperatorVerticleTest.validateAdvertisingToken(tokens.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(tokens.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); assertEquals(identityRequest.userIdentity.identityScope, advertisingToken.userIdentity.identityScope); assertEquals(identityRequest.userIdentity.identityType, advertisingToken.userIdentity.identityType); @@ -233,7 +178,7 @@ public void testGenerateAndRefreshForSiteIdUsingV4Token() { assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); assertNotNull(refreshResponse.getTokens()); - UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken(), TokenVersion.V4, IdentityScope.UID2, IdentityType.Email); + UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 7a0a8ea1f..a21c52974 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -618,7 +618,7 @@ private void assertTokenStatusMetrics(Integer siteId, TokenResponseStatsCollecto .tag("token_endpoint", String.valueOf(endpoint)) .tag("token_response_status", String.valueOf(responseStatus)) .tag("advertising_token_version", responseStatus == TokenResponseStatsCollector.ResponseStatus.Success ? String.valueOf(getTokenVersion()) : "null") - .tag("platformType", String.valueOf(platformType)) + .tag("platform_type", String.valueOf(platformType)) .counter().count(); assertEquals(1, actual); } diff --git a/src/test/java/com/uid2/operator/service/TokenUtilsTest.java b/src/test/java/com/uid2/operator/service/TokenUtilsTest.java new file mode 100644 index 000000000..2fb7af1fd --- /dev/null +++ b/src/test/java/com/uid2/operator/service/TokenUtilsTest.java @@ -0,0 +1,46 @@ +package com.uid2.operator.service; + +import com.uid2.shared.cloud.CloudStorageException; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static com.uid2.operator.service.TokenUtils.getSiteIdsUsingV4Tokens; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class TokenUtilsTest { + Set siteIdsV4TokensSet = new HashSet<>(Arrays.asList(127, 128)); + @Test + void getSiteIdsUsingV4Tokens_multipleSiteIds() { + Set actualSiteIdsV4TokensSet = getSiteIdsUsingV4Tokens("127, 128"); + assertEquals(siteIdsV4TokensSet, actualSiteIdsV4TokensSet); + } + + @Test + void getSiteIdsUsingV4Tokens_oneSiteIds() { + Set actualSiteIdsV4TokensSet = getSiteIdsUsingV4Tokens("127"); + assertEquals(new HashSet<>(List.of(127)), actualSiteIdsV4TokensSet); + } + + @Test + void getSiteIdsUsingV4Tokens_emptyInput() { + Set actualSiteIdsV4TokensSet = getSiteIdsUsingV4Tokens(""); + assertEquals(new HashSet<>(), actualSiteIdsV4TokensSet); + } + + @Test + void getSiteIdsUsingV4Tokens_inputContainsSpaces() { + Set actualSiteIdsV4TokensSet = getSiteIdsUsingV4Tokens(" 127 ,128 "); + assertEquals(siteIdsV4TokensSet, actualSiteIdsV4TokensSet); + } + + @Test + void getSiteIdsUsingV4Tokens_inputContainsInvalidInteger() { + assertThrows(IllegalArgumentException.class, + () -> getSiteIdsUsingV4Tokens(" 1 27 ,128 ")); + } +} From 8f54707d39a5f13f40d1ae16d435249502f637fd Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Mon, 3 Jun 2024 19:15:24 -0700 Subject: [PATCH 0468/1116] Address the comments --- .../uid2/operator/UIDOperatorServiceTest.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index e175b0e70..f384efb89 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -140,6 +140,12 @@ private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder tokenEncoder, return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } + private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expctedUserIdentity, UserIdentity actualUserIdentity) { + assertEquals(expctedUserIdentity.identityScope, actualUserIdentity.identityScope); + assertEquals(expctedUserIdentity.identityType, actualUserIdentity.identityType); + assertEquals(expctedUserIdentity.establishedAt, actualUserIdentity.establishedAt); + } + @ParameterizedTest @CsvSource({"123, V2","127, V4","128, V4"}) //site id 127 and 128 is for testing "site_ids_using_v4_tokens" public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { @@ -156,17 +162,13 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { UIDOperatorVerticleTest.validateAdvertisingToken(tokens.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(tokens.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); - assertEquals(identityRequest.userIdentity.identityScope, advertisingToken.userIdentity.identityScope); - assertEquals(identityRequest.userIdentity.identityType, advertisingToken.userIdentity.identityType); - assertEquals(identityRequest.userIdentity.establishedAt, advertisingToken.userIdentity.establishedAt); + assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.userIdentity, advertisingToken.userIdentity); RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); assertEquals(this.now, refreshToken.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, refreshToken.publisherIdentity.siteId); - assertEquals(identityRequest.userIdentity.identityScope, refreshToken.userIdentity.identityScope); - assertEquals(identityRequest.userIdentity.identityType, refreshToken.userIdentity.identityType); - assertEquals(identityRequest.userIdentity.establishedAt, refreshToken.userIdentity.establishedAt); + assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.userIdentity, refreshToken.userIdentity); setNow(Instant.now().plusSeconds(200)); @@ -182,18 +184,14 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); - assertEquals(advertisingToken.userIdentity.identityScope, advertisingToken2.userIdentity.identityScope); - assertEquals(advertisingToken.userIdentity.identityType, advertisingToken2.userIdentity.identityType); - assertEquals(advertisingToken.userIdentity.establishedAt, advertisingToken2.userIdentity.establishedAt); + assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingToken.userIdentity, advertisingToken2.userIdentity); assertArrayEquals(advertisingToken.userIdentity.id, advertisingToken2.userIdentity.id); RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getTokens().getRefreshToken()); assertEquals(this.now, refreshToken2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken2.expiresAt); assertEquals(refreshToken.publisherIdentity.siteId, refreshToken2.publisherIdentity.siteId); - assertEquals(refreshToken.userIdentity.identityScope, refreshToken2.userIdentity.identityScope); - assertEquals(refreshToken.userIdentity.identityType, refreshToken2.userIdentity.identityType); - assertEquals(refreshToken.userIdentity.establishedAt, refreshToken2.userIdentity.establishedAt); + assertIdentityScopeIdentityTypeAndEstablishedAt(refreshToken.userIdentity, refreshToken2.userIdentity); assertArrayEquals(refreshToken.userIdentity.id, refreshToken2.userIdentity.id); } From ca19e3ceae8d446850a1be2719ae4b99f36c24ba Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 4 Jun 2024 17:53:52 +0000 Subject: [PATCH 0469/1116] [CI Pipeline] Released Minor version: 5.37.0 --- pom.xml | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 97c7d32d3..8176b3b7a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.36.0 + 5.37.0 UTF-8 diff --git a/version.json b/version.json index 635f245e5..a614f77c7 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.36", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } +{ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", "version": "5.37", "publicReleaseRefSpec": [ "^refs/heads/master$", "^refs/heads/v\\d+(?:\\.\\d+)?$" ], "cloudBuild": { "setVersionVariables": true, "buildNumber": { "enabled": true, "includeCommitId": { "when": "always" } } } } From 1caa6d2ee8465bfcbd70fff25781eec55ca7870b Mon Sep 17 00:00:00 2001 From: asloob qureshi Date: Tue, 4 Jun 2024 11:07:04 -0700 Subject: [PATCH 0470/1116] Return timestamp in milliseconds for optout status API --- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 2 +- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 57eca0732..50d2118b7 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1746,7 +1746,7 @@ private void handleOptoutStatus(RoutingContext rc) { if (timestamp != -1) { JsonObject optOutJsonObj = new JsonObject(); optOutJsonObj.put("advertising_id", rawUId); - optOutJsonObj.put("opted_out_since", timestamp); + optOutJsonObj.put("opted_out_since", Instant.ofEpochSecond(timestamp).toEpochMilli()); optedOutJsonArray.add(optOutJsonObj); } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index a21c52974..d9c86a563 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -2214,8 +2214,10 @@ void optOutStatusRequest(Map optedOutIds, int optedOutCount, Role assertEquals(optedOutCount, optOutJsonArray.size()); for (int i = 0; i < optOutJsonArray.size(); ++i) { JsonObject optOutObject = optOutJsonArray.getJsonObject(i); - assertEquals(optedOutIds.get(optOutObject.getString("advertising_id")), - optOutObject.getLong("opted_out_since")); + String advertisingId = optOutObject.getString("advertising_id"); + assertTrue(optedOutIds.containsKey(advertisingId)); + long expectedTimestamp = Instant.ofEpochSecond(optedOutIds.get(advertisingId)).toEpochMilli(); + assertEquals(expectedTimestamp, optOutObject.getLong("opted_out_since")); } testContext.completeNow(); }); From e7b7f471745c80e8235e148f8ee6033a127a46aa Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 5 Jun 2024 17:10:33 +0000 Subject: [PATCH 0471/1116] [CI Pipeline] Released Patch version: 5.37.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8176b3b7a..21aa6c2ed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.0 + 5.37.3 UTF-8 From bb34ac2cdd06fcb5abf4537e98da303a87dfd4c8 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 11 Jun 2024 12:00:53 +1000 Subject: [PATCH 0472/1116] Added machine type and egress rule --- scripts/aws/UID_CloudFormation.template.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index 3fca4d373..ea3f90145 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -31,6 +31,10 @@ Parameters: - m5a.4xlarge - m5n.2xlarge - m5n.4xlarge + - m6i.2xlarge + - m6i.4xlarge + - r6i.2xlarge + - r6i.4xlarge ConstraintDescription: must be a valid EC2 instance type. RootVolumeSize: Description: Instance root volume size @@ -83,7 +87,7 @@ Metadata: DeployToEnvironment: default: UID2 environment to deploy to. Prod - production; Integ - integration test. InstanceType: - default: Instance Type for EC2. Minimum 4 vCPUs needed. M5, M5a, M5n Instance types are tested. Choose 2xlarge or 4xlarge. + default: Instance Type for EC2. Minimum 4 vCPUs needed. M5, M5a, M5n, M6i and R6i Instance types are tested. Choose 2xlarge or 4xlarge. SSHKeyName: default: Key Name for SSH to EC2 (required) RootVolumeSize: @@ -245,6 +249,11 @@ Resources: ToPort: '443' CidrIp: 0.0.0.0/0 Description: "Allow Outbound HTTPS" + - IpProtocol: udp + FromPort: '53' + ToPort: '53' + CidrIp: 0.0.0.0/0 + Description: "Allow Outbound DNS" VpcId: !Ref VpcId LaunchTemplate: Type: AWS::EC2::LaunchTemplate From c89806758fcde6a40974d1f6714e2bf61f4cde6d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 11 Jun 2024 13:27:32 +1000 Subject: [PATCH 0473/1116] Updated EUID template --- scripts/aws/EUID_CloudFormation.template.yml | 11 ++++++++++- scripts/aws/UID_CloudFormation.template.yml | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/scripts/aws/EUID_CloudFormation.template.yml b/scripts/aws/EUID_CloudFormation.template.yml index 1eeb2f5c5..bc4e2f8cc 100644 --- a/scripts/aws/EUID_CloudFormation.template.yml +++ b/scripts/aws/EUID_CloudFormation.template.yml @@ -31,6 +31,10 @@ Parameters: - m5a.4xlarge - m5n.2xlarge - m5n.4xlarge + - m6i.2xlarge + - m6i.4xlarge + - r6i.2xlarge + - r6i.4xlarge ConstraintDescription: must be a valid EC2 instance type. RootVolumeSize: Description: Instance root volume size @@ -83,7 +87,7 @@ Metadata: DeployToEnvironment: default: EUID environment to deploy to. Prod - production; Integ - integration test. InstanceType: - default: Instance Type for EC2. Minimum 4 vCPUs needed. M5, M5a, M5n Instance types are tested. Choose 2xlarge or 4xlarge. + default: Instance Type for EC2. Minimum 4 vCPUs needed. M5, M5a, M5n, M6i and R6i Instance types are tested. Choose 2xlarge or 4xlarge. SSHKeyName: default: Key Name for SSH to EC2 (required) RootVolumeSize: @@ -217,6 +221,11 @@ Resources: ToPort: '443' CidrIp: 0.0.0.0/0 Description: "Allow Outbound HTTPS" + - IpProtocol: udp + FromPort: '53' + ToPort: '53' + CidrIp: 0.0.0.0/0 + Description: "Allow Outbound DNS" VpcId: !Ref VpcId LaunchTemplate: Type: AWS::EC2::LaunchTemplate diff --git a/scripts/aws/UID_CloudFormation.template.yml b/scripts/aws/UID_CloudFormation.template.yml index ea3f90145..985d1560a 100644 --- a/scripts/aws/UID_CloudFormation.template.yml +++ b/scripts/aws/UID_CloudFormation.template.yml @@ -149,7 +149,7 @@ Mappings: Resources: KMSKey: Type: AWS::KMS::Key - Properties: + Properties: Description: Key for Secret Encryption EnableKeyRotation: true KeyPolicy: @@ -173,12 +173,12 @@ Resources: Resource: '*' SSMKEYAlias: Type: AWS::KMS::Alias - Properties: + Properties: AliasName: !Sub 'alias/uid-secret-${AWS::StackName}' TargetKeyId: !Ref KMSKey TokenSecret: Type: AWS::SecretsManager::Secret - Properties: + Properties: Description: UID2 Token KmsKeyId: !GetAtt KMSKey.Arn Name: !Sub 'uid2-config-stack-${AWS::StackName}' @@ -215,7 +215,7 @@ Resources: - Effect: Allow Action: 'secretsmanager:GetSecretValue' Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:uid2-config-stack-${AWS::StackName}*' - ManagedPolicyArns: + ManagedPolicyArns: - 'arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy' WorkerInstanceProfile: Type: 'AWS::IAM::InstanceProfile' @@ -269,11 +269,11 @@ Resources: Name: !Ref WorkerInstanceProfile ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI] InstanceType: !Ref InstanceType - EnclaveOptions: + EnclaveOptions: Enabled: true KeyName: !Ref SSHKeyName SecurityGroupIds: - - !Ref SecurityGroup + - !Ref SecurityGroup UserData: !Base64 Fn::Sub: | #!/bin/bash -ex @@ -291,12 +291,12 @@ Resources: LaunchTemplateId: !Ref LaunchTemplate Version: !GetAtt LaunchTemplate.LatestVersionNumber MetricsCollection: - - Granularity: 1Minute - Metrics: - - GroupTotalInstances + - Granularity: 1Minute + Metrics: + - GroupTotalInstances MaxSize: 1 MinSize: 1 - VPCZoneIdentifier: + VPCZoneIdentifier: - !Ref VpcSubnet1 - !Ref VpcSubnet2 Tags: From 1192cb9aede6a2d22a394384704eb076f0971fb6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 11 Jun 2024 03:38:21 +0000 Subject: [PATCH 0474/1116] [CI Pipeline] Released Patch version: 5.37.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 21aa6c2ed..4e9101ff7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.3 + 5.37.8 UTF-8 From 0994a5887674c325a40d44e1d4a62f884216cdeb Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 11 Jun 2024 14:25:56 +1000 Subject: [PATCH 0475/1116] Removing the packages json file as this is not used --- .github/workflows/node.js.yaml | 35 - js/package-lock.json | 10281 ------------------------------- js/package.json | 24 - 3 files changed, 10340 deletions(-) delete mode 100644 .github/workflows/node.js.yaml delete mode 100644 js/package-lock.json delete mode 100644 js/package.json diff --git a/.github/workflows/node.js.yaml b/.github/workflows/node.js.yaml deleted file mode 100644 index e4507da05..000000000 --- a/.github/workflows/node.js.yaml +++ /dev/null @@ -1,35 +0,0 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Node.js CI - -on: [pull_request, push, workflow_dispatch] - -env: - WORKING_DIR: js - - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [18.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - - steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - cache-dependency-path: ${{ env.WORKING_DIR }}/package-lock.json - - run: npm ci - working-directory: ${{ env.WORKING_DIR }} - - run: npm run build --if-present - working-directory: ${{ env.WORKING_DIR }} - - run: npm test - working-directory: ${{ env.WORKING_DIR }} diff --git a/js/package-lock.json b/js/package-lock.json deleted file mode 100644 index 05dbc6091..000000000 --- a/js/package-lock.json +++ /dev/null @@ -1,10281 +0,0 @@ -{ - "name": "uid2-sdk", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "uid2-sdk", - "version": "1.0.0", - "license": "Apache 2.0", - "devDependencies": { - "eslint": "^7.29.0", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-simple-import-sort": "^7.0.0", - "eslint-plugin-testing-library": "^4.6.0", - "jest": "^27.5.1" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.19.0", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.7.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz", - "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001402", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001402.tgz", - "integrity": "sha512-Mx4MlhXO5NwuvXGgVb+hg65HZ+bhUYsz8QtDGDo2QmaJS2GBX47Xfi2koL86lc8K+l+htXeTEB/Aeqvezoo6Ew==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", - "dev": true - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", - "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", - "dev": true - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.253", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.253.tgz", - "integrity": "sha512-1pezJ2E1UyBTGbA7fUlHdPSXQw1k+82VhTFLG5G0AUqLGvsZqFzleOblceqegZzxYX4kC7hGEEdzIQI9RZ1Cuw==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.25.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", - "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.0", - "has": "^1.0.3", - "is-core-module": "^2.7.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-simple-import-sort": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz", - "integrity": "sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==", - "dev": true, - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-plugin-testing-library": { - "version": "4.12.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-4.12.4.tgz", - "integrity": "sha512-XZtoeyIZKFTiH8vhwnCaTo/mNrLHoLyufY4kkNg+clzZFeThWPjp+0QfrLam1on1k3JGwiRvoLH/V4QdBaB2oA==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "^4.30.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0", - "npm": ">=6" - }, - "peerDependencies": { - "eslint": "^7.5.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", - "dev": true - }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", - "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==", - "dev": true - }, - "@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", - "dev": true, - "requires": { - "@babel/types": "^7.19.0", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - } - }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@types/node": { - "version": "18.7.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz", - "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==", - "dev": true - }, - "@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - } - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001402", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001402.tgz", - "integrity": "sha512-Mx4MlhXO5NwuvXGgVb+hg65HZ+bhUYsz8QtDGDo2QmaJS2GBX47Xfi2koL86lc8K+l+htXeTEB/Aeqvezoo6Ew==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decimal.js": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", - "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "electron-to-chromium": { - "version": "1.4.253", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.253.tgz", - "integrity": "sha512-1pezJ2E1UyBTGbA7fUlHdPSXQw1k+82VhTFLG5G0AUqLGvsZqFzleOblceqegZzxYX4kC7hGEEdzIQI9RZ1Cuw==", - "dev": true - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.25.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", - "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.0", - "has": "^1.0.3", - "is-core-module": "^2.7.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-simple-import-sort": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz", - "integrity": "sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==", - "dev": true, - "requires": {} - }, - "eslint-plugin-testing-library": { - "version": "4.12.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-4.12.4.tgz", - "integrity": "sha512-XZtoeyIZKFTiH8vhwnCaTo/mNrLHoLyufY4kkNg+clzZFeThWPjp+0QfrLam1on1k3JGwiRvoLH/V4QdBaB2oA==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "^4.30.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", - "dev": true - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, - "peer": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", - "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } -} diff --git a/js/package.json b/js/package.json deleted file mode 100644 index 706c610bd..000000000 --- a/js/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "uid2-sdk", - "version": "1.0.0", - "description": "UID2 Client SDK", - "author": "", - "license": "Apache 2.0", - "scripts": { - "lint": "eslint -c .eslintrc.js . ../static/js/uid2-sdk-2.0.0.js ../static/js/uid2-sdk-1.0.0.js", - "test": "jest" - }, - "jest": { - "testEnvironment": "jsdom", - "setupFilesAfterEnv": [ - "./setupJest.js" - ] - }, - "devDependencies": { - "eslint": "^7.29.0", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-simple-import-sort": "^7.0.0", - "eslint-plugin-testing-library": "^4.6.0", - "jest": "^27.5.1" - } -} From 595ba5c2d8663cd54759affdc499928b5c9f4c00 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 11 Jun 2024 04:34:58 +0000 Subject: [PATCH 0476/1116] [CI Pipeline] Released Patch version: 5.37.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4e9101ff7..df32aecdf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.8 + 5.37.12 UTF-8 From 60176733badd95cb8ab7ffabe6934c25885c418b Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Tue, 11 Jun 2024 16:54:57 +1000 Subject: [PATCH 0477/1116] Add logging to get information about refresh token version (#602) * Add logging to get information about refresh token version * Fix unit tests * Record metrics using labels to separate versions * Remove unnecessary import * Remove global registry metrics in TokenEncodingTest * Remove unnecessary variables --- .../service/EncryptedTokenEncoder.java | 13 +++++++++- .../operator/service/UIDOperatorService.java | 1 - .../operator/vertx/UIDOperatorVerticle.java | 25 +++++++++++++++++-- .../com/uid2/operator/TokenEncodingTest.java | 9 ++++--- .../operator/UIDOperatorVerticleTest.java | 4 +++ 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 19c8414f4..9be14663b 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -9,12 +9,13 @@ import com.uid2.shared.model.KeysetKey; import com.uid2.shared.model.TokenVersion; import io.vertx.core.buffer.Buffer; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Metrics; import java.time.Instant; import java.util.Base64; public class EncryptedTokenEncoder implements ITokenEncoder { - private final KeyManager keyManager; public EncryptedTokenEncoder(KeyManager keyManager) { @@ -259,13 +260,23 @@ public AdvertisingToken decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, Tok ); } + private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVersion) { + Counter.builder("uid2_refresh_token_served_count") + .description(String.format("Counter for the amount of refresh token %s served", tokenVersion.toString().toLowerCase())) + .tags("site_id", String.valueOf(siteId)) + .tags("refresh_token_version", tokenVersion.toString().toLowerCase()) + .register(Metrics.globalRegistry).increment(); + } + public byte[] encode(RefreshToken t, Instant asOf) { final KeysetKey serviceKey = this.keyManager.getRefreshKey(asOf); switch (t.version) { case V2: + recordRefreshTokenVersionCount(String.valueOf(t.publisherIdentity.siteId), TokenVersion.V2); return encodeV2(t, serviceKey); case V3: + recordRefreshTokenVersionCount(String.valueOf(t.publisherIdentity.siteId), TokenVersion.V3); return encodeV3(t, serviceKey); default: throw new ClientInputValidationException("RefreshToken version " + t.version + " not supported"); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 02e081092..950330a9e 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -2,7 +2,6 @@ import com.uid2.operator.model.*; import com.uid2.operator.util.PrivacyBits; -import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.shared.model.SaltEntry; import com.uid2.operator.store.IOptOutStore; import com.uid2.shared.store.ISaltProvider; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 50d2118b7..42c6f31bb 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -114,7 +114,6 @@ public class UIDOperatorVerticle extends AbstractVerticle { public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed. public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond(); private final Handler saltRetrievalResponseHandler; - private final int maxBidstreamLifetimeSeconds; private final int allowClockSkewSeconds; protected int maxSharingLifetimeSeconds; @@ -1778,13 +1777,34 @@ private void recordOptOutStatusEndpointStats(RoutingContext rc, int inputCount, optOutDistSummary.record(optOutCount); } + public TokenVersion getRefreshTokenVersion(String s) { + if (s != null && !s.isEmpty()) { + final byte[] bytes = EncodingUtils.fromBase64(s); + final Buffer b = Buffer.buffer(bytes); + if (b.getByte(1) == TokenVersion.V3.rawVersion) { + return TokenVersion.V3; + } else if (b.getByte(0) == TokenVersion.V2.rawVersion) { + return TokenVersion.V2; + } + } + return null; + } + + private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVersion) { + Counter.builder("uid2_refresh_token_received_count") + .description(String.format("Counter for the amount of refresh token %s received", tokenVersion.toString().toLowerCase())) + .tags("site_id", siteId) + .tags("refresh_token_version", tokenVersion.toString().toLowerCase()) + .register(Metrics.globalRegistry).increment(); + + } + private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { final RefreshToken refreshToken; try { if (AuthMiddleware.isAuthenticated(rc)) { rc.put(Const.RoutingContextData.SiteId, AuthMiddleware.getAuthClient(ClientKey.class, rc).getSiteId()); } - refreshToken = this.encoder.decodeRefreshToken(tokenStr); } catch (ClientInputValidationException cie) { return RefreshResponse.Invalid; @@ -1795,6 +1815,7 @@ private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { if (!AuthMiddleware.isAuthenticated(rc)) { rc.put(Const.RoutingContextData.SiteId, refreshToken.publisherIdentity.siteId); } + recordRefreshTokenVersionCount(String.valueOf(rc.data().get(Const.RoutingContextData.SiteId)), this.getRefreshTokenVersion(tokenStr)); return this.idService.refreshIdentity(refreshToken); } diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 0c9d38644..c77c81b78 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -11,17 +11,16 @@ import com.uid2.shared.store.reader.RotatingKeysetKeyStore; import com.uid2.shared.store.reader.RotatingKeysetProvider; import com.uid2.shared.store.scope.GlobalScope; +import io.micrometer.core.instrument.Metrics; import io.vertx.core.buffer.Buffer; import io.vertx.core.json.JsonObject; import org.junit.Assert; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.ValueSource; import java.time.Instant; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class TokenEncodingTest { @@ -80,6 +79,10 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 25 : 2); assertEquals(Data.RefreshKeySiteId, keyManager.getSiteIdFromKeyId(keyId)); + + assertNotNull(Metrics.globalRegistry + .get("uid2_refresh_token_served_count") + .counter()); } @ParameterizedTest diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index d9c86a563..e900fa96f 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1745,6 +1745,8 @@ void tokenRefreshExpiredTokenAuthenticated(String apiVersion, Vertx vertx, Vertx sendTokenRefresh(apiVersion, vertx, testContext, refreshToken, bodyJson.getString("refresh_response_key"), 400, refreshRespJson -> { assertEquals("expired_token", refreshRespJson.getString("status")); + assertNotNull(Metrics.globalRegistry + .get("uid2_refresh_token_received_count").counter()); testContext.completeNow(); }); }); @@ -1763,6 +1765,8 @@ void tokenRefreshExpiredTokenUnauthenticated(String apiVersion, Vertx vertx, Ver sendTokenRefresh(apiVersion, vertx, testContext, refreshToken, "", 400, refreshRespJson -> { assertEquals("error", refreshRespJson.getString("status")); + assertNotNull(Metrics.globalRegistry + .get("uid2_refresh_token_received_count").counter()); testContext.completeNow(); }); }); From 3790a3182e6ba1d320617b4a0446039143bca29f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 11 Jun 2024 06:58:04 +0000 Subject: [PATCH 0478/1116] [CI Pipeline] Released Patch version: 5.37.15 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index df32aecdf..0754e7e4b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.12 + 5.37.15 UTF-8 From 6bd7b741026ee527d09cdf469dbc06d060d795ce Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 11 Jun 2024 14:02:55 -0600 Subject: [PATCH 0479/1116] copy changes from Thomas's branch --- pom.xml | 21 +- src/main/java/com/uid2/operator/Main.java | 3 +- .../operator/service/ShutdownService.java | 11 + .../vertx/OperatorShutdownHandler.java | 11 +- .../operator/OperatorShutdownHandlerTest.java | 221 +++++++----------- 5 files changed, 120 insertions(+), 147 deletions(-) create mode 100644 src/main/java/com/uid2/operator/service/ShutdownService.java diff --git a/pom.xml b/pom.xml index 0754e7e4b..158e6a774 100644 --- a/pom.xml +++ b/pom.xml @@ -12,18 +12,21 @@ UTF-8 4.5.3 1.0.22 - 5.7.2 - 5.7.2 + 5.10.1 + 5.10.1 3.0.0 com.uid2.operator.vertx.UIDOperatorVerticle - 1.1.0 + 1.12.2 2.0.0-f968aec0e3 2.0.0-f7c174410e 2.0.4-ef52553c57 2.0.0-21f950573a 7.9.0 ${project.version} + 21 + 21 + 21 @@ -118,14 +121,14 @@ org.mockito - mockito-inline - 3.7.7 + mockito-core + 5.10.0 test org.assertj assertj-core - 3.23.1 + 3.25.2 test @@ -260,10 +263,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.1 - 11 - 11 + 21 + 21 diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index d71222060..69eb83c19 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -8,6 +8,7 @@ import com.uid2.operator.monitoring.OperatorMetrics; import com.uid2.operator.monitoring.StatsCollectorVerticle; import com.uid2.operator.service.SecureLinkValidatorService; +import com.uid2.operator.service.ShutdownService; import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.operator.store.CloudSyncOptOutStore; import com.uid2.operator.store.OptOutCloudStorage; @@ -95,7 +96,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception { boolean useStorageMock = config.getBoolean(Const.Config.StorageMockProp, false); this.clientSideTokenGenerate = config.getBoolean(Const.Config.EnableClientSideTokenGenerate, false); this.validateServiceLinks = config.getBoolean(Const.Config.ValidateServiceLinks, false); - this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(config.getInteger(Const.Config.SaltsExpiredShutdownHours, 12)), Clock.systemUTC()); + this.shutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(config.getInteger(Const.Config.SaltsExpiredShutdownHours, 12)), Clock.systemUTC(), new ShutdownService()); String coreAttestUrl = this.config.getString(Const.Config.CoreAttestUrlProp); diff --git a/src/main/java/com/uid2/operator/service/ShutdownService.java b/src/main/java/com/uid2/operator/service/ShutdownService.java new file mode 100644 index 000000000..e4cd3f57f --- /dev/null +++ b/src/main/java/com/uid2/operator/service/ShutdownService.java @@ -0,0 +1,11 @@ +package com.uid2.operator.service; + +public class ShutdownService { + public void Shutdown(int status) { + System.exit(status); + + // according to the docks, this should not be reached as System.exit does not complete either normally or abruptly. + // Added for safety + throw new RuntimeException("JVM Requested to shut down"); + } +} \ No newline at end of file diff --git a/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java b/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java index 218320b85..113c14d3e 100644 --- a/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java +++ b/src/main/java/com/uid2/operator/vertx/OperatorShutdownHandler.java @@ -1,5 +1,6 @@ package com.uid2.operator.vertx; +import com.uid2.operator.service.ShutdownService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.utils.Pair; @@ -19,11 +20,13 @@ public class OperatorShutdownHandler { private final AtomicReference saltFailureStartTime = new AtomicReference<>(null); private final AtomicReference lastSaltFailureLogTime = new AtomicReference<>(null); private final Clock clock; + private final ShutdownService shutdownService; - public OperatorShutdownHandler(Duration attestShutdownWaitTime, Duration saltShutdownWaitTime, Clock clock) { + public OperatorShutdownHandler(Duration attestShutdownWaitTime, Duration saltShutdownWaitTime, Clock clock, ShutdownService shutdownService) { this.attestShutdownWaitTime = attestShutdownWaitTime; this.saltShutdownWaitTime = saltShutdownWaitTime; this.clock = clock; + this.shutdownService = shutdownService; } public void handleSaltRetrievalResponse(Boolean expired) { @@ -36,7 +39,7 @@ public void handleSaltRetrievalResponse(Boolean expired) { saltFailureStartTime.set(clock.instant()); } else if(Duration.between(t, clock.instant()).compareTo(this.saltShutdownWaitTime) > 0) { LOGGER.error("salts have been in expired state for too long. shutting down operator"); - System.exit(1); + this.shutdownService.Shutdown(1); } } } @@ -52,7 +55,7 @@ public void logSaltFailureAtInterval() { public void handleAttestResponse(Pair response) { if (response.left() == 401) { LOGGER.error("core attestation failed with 401, shutting down operator, core response: " + response.right()); - System.exit(1); + this.shutdownService.Shutdown(1); } if (response.left() == 200) { attestFailureStartTime.set(null); @@ -62,7 +65,7 @@ public void handleAttestResponse(Pair response) { attestFailureStartTime.set(clock.instant()); } else if (Duration.between(t, clock.instant()).compareTo(this.attestShutdownWaitTime) > 0) { LOGGER.error("core attestation has been in failed state for too long. shutting down operator"); - System.exit(1); + this.shutdownService.Shutdown(1); } } } diff --git a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java index d7a7797ea..a811b2fdc 100644 --- a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java +++ b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java @@ -3,6 +3,7 @@ import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; +import com.uid2.operator.service.ShutdownService; import com.uid2.operator.vertx.OperatorShutdownHandler; import io.vertx.core.Vertx; import io.vertx.junit5.VertxExtension; @@ -24,31 +25,24 @@ import java.time.temporal.ChronoUnit; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(VertxExtension.class) public class OperatorShutdownHandlerTest { private AutoCloseable mocks; @Mock private Clock clock; + @Mock private ShutdownService shutdownService; private OperatorShutdownHandler operatorShutdownHandler; - class NoExitSecurityManager extends SecurityManager { - @Override - public void checkPermission(Permission perm) { } - @Override - public void checkExit(int status) { - super.checkExit(status); - throw new RuntimeException(String.valueOf(status)); - } - } @BeforeEach void beforeEach() { mocks = MockitoAnnotations.openMocks(this); when(clock.instant()).thenAnswer(i -> Instant.now()); - this.operatorShutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), clock); + doThrow(new RuntimeException()).when(shutdownService).Shutdown(1); + this.operatorShutdownHandler = new OperatorShutdownHandler(Duration.ofHours(12), Duration.ofHours(12), clock, shutdownService); } @AfterEach @@ -57,154 +51,115 @@ void afterEach() throws Exception { } @Test - void shutdownOnAttest401(Vertx vertx, VertxTestContext testContext) { - SecurityManager origSecurityManager = System.getSecurityManager(); + void shutdownOnAttest401(VertxTestContext testContext) { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + + // Revoke auth try { - System.setSecurityManager(new NoExitSecurityManager()); - - ListAppender logWatcher = new ListAppender<>(); - logWatcher.start(); - ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - - // Revoke auth - try { - this.operatorShutdownHandler.handleAttestResponse(Pair.of(401, "Unauthorized")); - } catch (RuntimeException e) { - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("core attestation failed with 401, shutting down operator, core response: ")); - testContext.completeNow(); - } - } finally { - System.setSecurityManager(origSecurityManager); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(401, "Unauthorized")); + } catch (RuntimeException e) { + verify(shutdownService).Shutdown(1); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("core attestation failed with 401, shutting down operator, core response: ")); + testContext.completeNow(); } } @Test - void shutdownOnAttestFailedTooLong(Vertx vertx, VertxTestContext testContext) { - SecurityManager origSecurityManager = System.getSecurityManager(); - try { - System.setSecurityManager(new NoExitSecurityManager()); + void shutdownOnAttestFailedTooLong(VertxTestContext testContext) { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - ListAppender logWatcher = new ListAppender<>(); - logWatcher.start(); - ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); + try { this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); - - when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); - try { - this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); - } catch (RuntimeException e) { - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("core attestation has been in failed state for too long. shutting down operator")); - testContext.completeNow(); - } - } finally { - System.setSecurityManager(origSecurityManager); + } catch (RuntimeException e) { + verify(shutdownService).Shutdown(1); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("core attestation has been in failed state for too long. shutting down operator")); + testContext.completeNow(); } } @Test - void attestRecoverOnSuccess(Vertx vertx, VertxTestContext testContext) { - SecurityManager origSecurityManager = System.getSecurityManager(); - try { - System.setSecurityManager(new NoExitSecurityManager()); + void attestRecoverOnSuccess(VertxTestContext testContext) { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - ListAppender logWatcher = new ListAppender<>(); - logWatcher.start(); - ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); + this.operatorShutdownHandler.handleAttestResponse(Pair.of(200, "")); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); + assertDoesNotThrow(() -> { this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); - when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); - this.operatorShutdownHandler.handleAttestResponse(Pair.of(200, "")); - - when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); - assertDoesNotThrow(() -> { - this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); - }); - testContext.completeNow(); - } finally { - System.setSecurityManager(origSecurityManager); - } + }); + testContext.completeNow(); } @Test - void shutdownOnSaltsExpiredTooLong(Vertx vertx, VertxTestContext testContext) { - SecurityManager origSecurityManager = System.getSecurityManager(); - try { - System.setSecurityManager(new NoExitSecurityManager()); + void shutdownOnSaltsExpiredTooLong(VertxTestContext testContext) { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - ListAppender logWatcher = new ListAppender<>(); - logWatcher.start(); - ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); + Assertions.assertThrows(RuntimeException.class, () -> { this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - - when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS).plusSeconds(60)); - Assertions.assertThrows(RuntimeException.class, () -> { - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - }); - Assertions.assertAll("Expired Salts Log Messages", - () -> Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")), - () -> Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator")), - () -> Assertions.assertEquals(3, logWatcher.list.size())); - - testContext.completeNow(); - } finally { - System.setSecurityManager(origSecurityManager); - } + }); + verify(shutdownService).Shutdown(1); + Assertions.assertAll("Expired Salts Log Messages", + () -> Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")), + () -> Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator")), + () -> Assertions.assertEquals(3, logWatcher.list.size())); + + testContext.completeNow(); } @Test - void saltsRecoverOnSuccess(Vertx vertx, VertxTestContext testContext) { - SecurityManager origSecurityManager = System.getSecurityManager(); - try { - System.setSecurityManager(new NoExitSecurityManager()); - - ListAppender logWatcher = new ListAppender<>(); - logWatcher.start(); - ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); - - when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); - assertDoesNotThrow(() -> { - this.operatorShutdownHandler.handleSaltRetrievalResponse(false); - }); - Assertions.assertEquals(2, logWatcher.list.size()); - - testContext.completeNow(); - } finally { - System.setSecurityManager(origSecurityManager); - } + void saltsRecoverOnSuccess(VertxTestContext testContext) { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(6, ChronoUnit.HOURS)); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); + + when(clock.instant()).thenAnswer(i -> Instant.now().plus(12, ChronoUnit.HOURS)); + assertDoesNotThrow(() -> { + this.operatorShutdownHandler.handleSaltRetrievalResponse(false); + }); + Assertions.assertEquals(2, logWatcher.list.size()); + + testContext.completeNow(); } @Test - void saltsLogErrorAtInterval(Vertx vertx, VertxTestContext testContext) { - SecurityManager origSecurityManager = System.getSecurityManager(); - try { - System.setSecurityManager(new NoExitSecurityManager()); - - ListAppender logWatcher = new ListAppender<>(); - logWatcher.start(); - ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); - - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); - when(clock.instant()).thenAnswer(i -> Instant.now().plus(9, ChronoUnit.MINUTES)); - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertEquals(1, logWatcher.list.size()); - when(clock.instant()).thenAnswer(i -> Instant.now().plus(11, ChronoUnit.MINUTES)); - this.operatorShutdownHandler.handleSaltRetrievalResponse(true); - Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); - Assertions.assertEquals(2, logWatcher.list.size()); - - testContext.completeNow(); - } finally { - System.setSecurityManager(origSecurityManager); - } + void saltsLogErrorAtInterval(VertxTestContext testContext) { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(OperatorShutdownHandler.class)).addAppender(logWatcher); + + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("all salts are expired")); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(9, ChronoUnit.MINUTES)); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertEquals(1, logWatcher.list.size()); + when(clock.instant()).thenAnswer(i -> Instant.now().plus(11, ChronoUnit.MINUTES)); + this.operatorShutdownHandler.handleSaltRetrievalResponse(true); + Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")); + Assertions.assertEquals(2, logWatcher.list.size()); + + testContext.completeNow(); } } From c5ba1c331f95a76913f49c792b5b817781e01dd1 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 11:27:08 -0600 Subject: [PATCH 0480/1116] specify release and update docker base --- Dockerfile | 4 ++-- pom.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0318961b1..a19a358dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/11.0.22_7-jre-alpine/images/sha256-d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a?context=explore -FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/21.0.3_9-jre-alpine/images/sha256-3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253?context=explore +FROM eclipse-temurin@sha256:3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253 WORKDIR /app EXPOSE 8080 diff --git a/pom.xml b/pom.xml index 158e6a774..eae8137bd 100644 --- a/pom.xml +++ b/pom.xml @@ -267,6 +267,7 @@ 21 21 + 21 From 964237260e9d60dc1ee213f5fcab6208d6743e0a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 11:52:28 -0600 Subject: [PATCH 0481/1116] build and test using java 21 --- .github/workflows/build-and-test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index 4aad7e54c..00695f1db 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -4,4 +4,6 @@ on: [pull_request, push, workflow_dispatch] jobs: build: uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-build-and-test.yaml@v2 + with: + java_version: 21 secrets: inherit \ No newline at end of file From a1d9baf07d5d6655f0c0c56aa94aad2eea435bb9 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 12:02:18 -0600 Subject: [PATCH 0482/1116] upgrade jacoco --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eae8137bd..f1002b4e3 100644 --- a/pom.xml +++ b/pom.xml @@ -206,6 +206,11 @@ 4.3.2 test + + org.jacoco + jacoco-maven-plugin + 0.8.12 + @@ -251,7 +256,7 @@ org.jacoco jacoco-maven-plugin - 0.8.8 + 0.8.12 From 400a985978fe5ee2c7c05e57f2e897874e0217df Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 12:17:23 -0600 Subject: [PATCH 0483/1116] java versions docker builds --- .github/workflows/publish-azure-cc-enclave-docker.yaml | 2 +- .github/workflows/publish-gcp-oidc-enclave-docker.yaml | 2 +- .github/workflows/publish-public-operator-docker-image.yaml | 1 + scripts/aws/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 5d983fb28..3b8c1625a 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -94,7 +94,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '21' - name: Checkout full history on Main uses: actions/checkout@v4 diff --git a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml index 797c3e61b..5c7a59946 100644 --- a/.github/workflows/publish-gcp-oidc-enclave-docker.yaml +++ b/.github/workflows/publish-gcp-oidc-enclave-docker.yaml @@ -96,7 +96,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '21' - name: Checkout full history on Main uses: actions/checkout@v4 diff --git a/.github/workflows/publish-public-operator-docker-image.yaml b/.github/workflows/publish-public-operator-docker-image.yaml index e54e91d57..d2e113764 100644 --- a/.github/workflows/publish-public-operator-docker-image.yaml +++ b/.github/workflows/publish-public-operator-docker-image.yaml @@ -66,6 +66,7 @@ jobs: version_number_input: ${{ inputs.version_number_input }} force_release: 'no' # Do not create a release for the component builds, will be created by the parent vulnerability_severity: ${{ inputs.vulnerability_severity }} + java_version: 21 secrets: inherit e2e: diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 359547e66..60a16fefe 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:11.0.16-jre-slim-bullseye +FROM openjdk:21-slim-bullseye WORKDIR /app From e816ccf8257ad947a64d261a4572f5ffd2ad157c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 12 Jun 2024 18:38:51 +0000 Subject: [PATCH 0484/1116] [CI Pipeline] Released Snapshot version: 5.37.16-alpha-85-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f1002b4e3..ea732a36a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.15 + 5.37.16-alpha-85-SNAPSHOT UTF-8 From 0d97f3824ed287ce4d786a2486d915271acc1b82 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 13:27:08 -0600 Subject: [PATCH 0485/1116] validate-image java version --- .github/workflows/validate-image.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/validate-image.yaml b/.github/workflows/validate-image.yaml index 855782e38..524f19102 100644 --- a/.github/workflows/validate-image.yaml +++ b/.github/workflows/validate-image.yaml @@ -24,6 +24,7 @@ jobs: failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'default' + java_version: 21 secrets: inherit build-publish-docker-aws: uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-validate-image.yaml@v2 @@ -31,6 +32,7 @@ jobs: failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'aws' + java_version: 21 secrets: inherit needs: [build-publish-docker-default] build-publish-docker-gcp: @@ -39,6 +41,7 @@ jobs: failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'gcp' + java_version: 21 secrets: inherit needs: [build-publish-docker-aws] build-publish-docker-azure: @@ -47,5 +50,6 @@ jobs: failure_severity: ${{ inputs.failure_severity || 'CRITICAL,HIGH' }} fail_on_error: ${{ inputs.fail_on_error || true }} cloud_provider: 'azure' + java_version: 21 secrets: inherit needs: [build-publish-docker-gcp] \ No newline at end of file From 25f451cfcb799f05c15d53d21c048c91447c6206 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 12 Jun 2024 20:44:57 +0000 Subject: [PATCH 0486/1116] [CI Pipeline] Released Snapshot version: 5.37.17-alpha-139-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea732a36a..253ac964a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.16-alpha-85-SNAPSHOT + 5.37.17-alpha-139-SNAPSHOT UTF-8 From 989cb0e915219df1a48242480f380262b7966f05 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 14:46:39 -0600 Subject: [PATCH 0487/1116] scripts/gcp-oidc dockerfile base image --- scripts/gcp-oidc/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gcp-oidc/Dockerfile b/scripts/gcp-oidc/Dockerfile index b8fa9c54a..a3f81e6b9 100644 --- a/scripts/gcp-oidc/Dockerfile +++ b/scripts/gcp-oidc/Dockerfile @@ -1,5 +1,5 @@ -# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/11.0.22_7-jre-alpine/images/sha256-d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a?context=explore -FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/21.0.3_9-jre-alpine/images/sha256-3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253?context=explore +FROM eclipse-temurin@sha256:3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253 LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_ENVIRONMENT,CORE_BASE_URL,OPTOUT_BASE_URL" LABEL "tee.launch_policy.log_redirect"="always" From cc4232ea17c54f148e6af56495447d12f6dd8fce Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 14:58:01 -0600 Subject: [PATCH 0488/1116] scripts\azure-cc\Dockerfile base image --- scripts/azure-cc/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/azure-cc/Dockerfile b/scripts/azure-cc/Dockerfile index b46ffeee2..42db1df6e 100644 --- a/scripts/azure-cc/Dockerfile +++ b/scripts/azure-cc/Dockerfile @@ -1,5 +1,5 @@ -# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/11.0.22_7-jre-alpine/images/sha256-d7a82981336958683f147f17396fe2219cb1072a5853e8a8ef16d07f0535343a?context=explore -FROM eclipse-temurin@sha256:564eb67091b2cda82952299b4be52bf1b039289234b52f46057fe1286c173b71 +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/21.0.3_9-jre-alpine/images/sha256-3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253?context=explore +FROM eclipse-temurin@sha256:3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253 # Install Packages RUN apk update && apk add jq From 520358aaa2e71f05b16c14ae0c6161b8291c010a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 12 Jun 2024 20:58:43 +0000 Subject: [PATCH 0489/1116] [CI Pipeline] Released Snapshot version: 5.37.18-alpha-140-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 253ac964a..5dc26e904 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.17-alpha-139-SNAPSHOT + 5.37.18-alpha-140-SNAPSHOT UTF-8 From 02d59c42b5ebb35b2ef8292439559978d980c9e6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 12 Jun 2024 21:14:04 +0000 Subject: [PATCH 0490/1116] [CI Pipeline] Released Snapshot version: 5.37.19-alpha-108-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5dc26e904..e9d01da9b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.18-alpha-140-SNAPSHOT + 5.37.19-alpha-108-SNAPSHOT UTF-8 From 026d11aee687de80e0698ad4cda4fd7e829c7d3c Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 12 Jun 2024 15:42:49 -0600 Subject: [PATCH 0491/1116] updating aws java versions --- Dockerfile.nitro.builder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index eaca75f74..daba7ab13 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -4,7 +4,7 @@ ENV enclave_platform="aws-nitro" # install build-essential, openjdk, maven, git RUN apt-get update -y \ - && apt-get install -y curl -y build-essential pkg-config libssl-dev cmake openjdk-11-jdk maven git \ + && apt-get install -y curl -y build-essential pkg-config libssl-dev cmake openjdk-21-jdk maven git \ && rm -rf /var/lib/apt/lists/* # install rust From fdb31dd82eb639aab58470e0ca8c1715713e7151 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 12 Jun 2024 21:44:57 +0000 Subject: [PATCH 0492/1116] [CI Pipeline] Released Snapshot version: 5.37.20-alpha-146-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9d01da9b..5f75abbcf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.19-alpha-108-SNAPSHOT + 5.37.20-alpha-146-SNAPSHOT UTF-8 From 3f8df2a3e6047117860b8032388eea0a46064256 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 13 Jun 2024 12:26:37 -0600 Subject: [PATCH 0493/1116] debian -> ubuntu for openjdk-21-jdk package --- Dockerfile.nitro.builder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index daba7ab13..d79c26077 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -1,4 +1,4 @@ -FROM debian:bullseye +FROM ubuntu:24.04 ENV enclave_platform="aws-nitro" From 58f9baed885170845a726a872fc21df49b9c5e76 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 13 Jun 2024 18:27:49 +0000 Subject: [PATCH 0494/1116] [CI Pipeline] Released Snapshot version: 5.37.21-alpha-147-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5f75abbcf..28821dfcd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.20-alpha-146-SNAPSHOT + 5.37.21-alpha-147-SNAPSHOT UTF-8 From 5a4ee5e35ffdd8356085da655a33e7475f26d5a5 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 13 Jun 2024 19:45:55 +0000 Subject: [PATCH 0495/1116] [CI Pipeline] Released Snapshot version: 5.37.22-alpha-148-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 28821dfcd..4b42315d6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.21-alpha-147-SNAPSHOT + 5.37.22-alpha-148-SNAPSHOT UTF-8 From 6c0d87f8605136510a244b2d583ea096f07cfe9a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 13 Jun 2024 15:24:00 -0600 Subject: [PATCH 0496/1116] testing build on debian again --- Dockerfile.nitro.builder | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index d79c26077..1755f4811 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -1,10 +1,10 @@ -FROM ubuntu:24.04 +FROM debian:bullseye ENV enclave_platform="aws-nitro" # install build-essential, openjdk, maven, git RUN apt-get update -y \ - && apt-get install -y curl -y build-essential pkg-config libssl-dev cmake openjdk-21-jdk maven git \ + && apt-get install -y curl -y build-essential pkg-config libssl-dev cmake openjdk-21 maven git \ && rm -rf /var/lib/apt/lists/* # install rust From 5c7837596a231dc0e0016f61cb64d681b33b4d93 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 13 Jun 2024 21:24:56 +0000 Subject: [PATCH 0497/1116] [CI Pipeline] Released Snapshot version: 5.37.23-alpha-149-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b42315d6..1a1192cef 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.22-alpha-148-SNAPSHOT + 5.37.23-alpha-149-SNAPSHOT UTF-8 From a51bccbcbc38688e11bfa5361ec6fcb63fa5f15d Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 13:58:51 -0600 Subject: [PATCH 0498/1116] try alpine w/ eclipse temurin --- Dockerfile.nitro.builder | 4 ++-- scripts/aws/Dockerfile | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index 1755f4811..15cb26371 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -1,10 +1,10 @@ -FROM debian:bullseye +FROM alpine:3.20 ENV enclave_platform="aws-nitro" # install build-essential, openjdk, maven, git RUN apt-get update -y \ - && apt-get install -y curl -y build-essential pkg-config libssl-dev cmake openjdk-21 maven git \ + && apt-get install -y curl -y build-essential pkg-config libssl-dev cmake openjdk-21-jdk maven git \ && rm -rf /var/lib/apt/lists/* # install rust diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 60a16fefe..73d911a8a 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -1,4 +1,5 @@ -FROM openjdk:21-slim-bullseye +# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/21.0.3_9-jre-alpine/images/sha256-3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253?context=explore +FROM eclipse-temurin@sha256:3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253 WORKDIR /app From 1ec7915c8ca13d7e803263d06b6cce6303ca9f99 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 20:00:21 +0000 Subject: [PATCH 0499/1116] [CI Pipeline] Released Snapshot version: 5.37.24-alpha-151-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1a1192cef..f32540209 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.23-alpha-149-SNAPSHOT + 5.37.24-alpha-151-SNAPSHOT UTF-8 From 8b52a92fa3e8d72f42ba7b15974aadf20378061a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 14:05:47 -0600 Subject: [PATCH 0500/1116] ubuntu --- Dockerfile.nitro.builder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index 15cb26371..d79c26077 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -1,4 +1,4 @@ -FROM alpine:3.20 +FROM ubuntu:24.04 ENV enclave_platform="aws-nitro" From 0ed4c74bffd4ff5bad9d317a0e8385294cdf450d Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 20:06:52 +0000 Subject: [PATCH 0501/1116] [CI Pipeline] Released Snapshot version: 5.37.25-alpha-152-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f32540209..45748ce6b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.24-alpha-151-SNAPSHOT + 5.37.25-alpha-152-SNAPSHOT UTF-8 From 35191347616b7b2f300396f3c53fdbd9dffdecb7 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 14:24:18 -0600 Subject: [PATCH 0502/1116] ubuntu --- scripts/aws/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 73d911a8a..67c91635a 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -1,5 +1,5 @@ -# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/21.0.3_9-jre-alpine/images/sha256-3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253?context=explore -FROM eclipse-temurin@sha256:3c40389d278c7129d9032c5f3ce68fb150c2869b5e107ea801b150a2ae653253 +# https://hub.docker.com/layers/library/eclipse-temurin/21-jre-jammy/images/sha256-3186dd88a59659929855a6bb785b0528c812eb0b03d97fd6e2221526547ed322?context=explore +FROM eclipse-temurin:21-jre-jammy WORKDIR /app From f00d3387cc846f1659988be8a535417dc550c38f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 20:26:01 +0000 Subject: [PATCH 0503/1116] [CI Pipeline] Released Snapshot version: 5.37.26-alpha-153-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 45748ce6b..c95841c1e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.25-alpha-152-SNAPSHOT + 5.37.26-alpha-153-SNAPSHOT UTF-8 From cb22b334c0028a271a98e97acb184642975110b7 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 14:39:58 -0600 Subject: [PATCH 0504/1116] testing build --- scripts/aws/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 67c91635a..6adaf0d3c 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -18,7 +18,7 @@ ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" COPY ./syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ COPY ./syslog-ng-ose-pub.asc /app/dep/ -RUN apt update -y \ +RUN apt-get update -y \ && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ && apt-key add /app/dep/syslog-ng-ose-pub.asc \ && apt-get install /app/dep/syslog-ng-core_4.6.0-1_amd64.deb \ From f0ff20c956ceab9ed47afa2c1a22b73b71516bb9 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 20:41:06 +0000 Subject: [PATCH 0505/1116] [CI Pipeline] Released Snapshot version: 5.37.27-alpha-154-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c95841c1e..73653aaa2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.26-alpha-153-SNAPSHOT + 5.37.27-alpha-154-SNAPSHOT UTF-8 From 8713d258f606d63622e725358ffed6a8d426cb98 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 14:50:21 -0600 Subject: [PATCH 0506/1116] testing build --- scripts/aws/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 6adaf0d3c..dca326ab3 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -19,7 +19,7 @@ COPY ./syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ COPY ./syslog-ng-ose-pub.asc /app/dep/ RUN apt-get update -y \ - && apt install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ + && apt-get install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ && apt-key add /app/dep/syslog-ng-ose-pub.asc \ && apt-get install /app/dep/syslog-ng-core_4.6.0-1_amd64.deb \ && rm -rf /var/lib/apt/lists/* \ From 3eb8b3ff7e5a40567d082d9cd445790539ca9df9 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 14:57:15 -0600 Subject: [PATCH 0507/1116] testing build --- scripts/aws/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index dca326ab3..2cea22d8e 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -20,6 +20,7 @@ COPY ./syslog-ng-ose-pub.asc /app/dep/ RUN apt-get update -y \ && apt-get install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ + && apt-get autoremove \ && apt-key add /app/dep/syslog-ng-ose-pub.asc \ && apt-get install /app/dep/syslog-ng-core_4.6.0-1_amd64.deb \ && rm -rf /var/lib/apt/lists/* \ From 21f6682c2b29501d959bcaec699897648109e2d5 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 20:58:02 +0000 Subject: [PATCH 0508/1116] [CI Pipeline] Released Snapshot version: 5.37.28-alpha-155-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 73653aaa2..3c6b26f7e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.27-alpha-154-SNAPSHOT + 5.37.28-alpha-155-SNAPSHOT UTF-8 From 6948aecb7e2ea25aedab1f61123879210eae0e62 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 16:01:42 -0600 Subject: [PATCH 0509/1116] install libssl1.1 from focal package --- scripts/aws/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/aws/Dockerfile b/scripts/aws/Dockerfile index 2cea22d8e..8ea0d9cec 100644 --- a/scripts/aws/Dockerfile +++ b/scripts/aws/Dockerfile @@ -18,9 +18,9 @@ ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" COPY ./syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ COPY ./syslog-ng-ose-pub.asc /app/dep/ -RUN apt-get update -y \ - && apt-get install -y pkg-config libssl-dev net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ - && apt-get autoremove \ +RUN echo "deb http://security.ubuntu.com/ubuntu focal-security main" | tee -a /etc/apt/sources.list \ + && apt update -y \ + && apt install -y pkg-config libssl-dev libssl1.1 net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ && apt-key add /app/dep/syslog-ng-ose-pub.asc \ && apt-get install /app/dep/syslog-ng-core_4.6.0-1_amd64.deb \ && rm -rf /var/lib/apt/lists/* \ From d4f8d6418b24634221bb6f64eae8ced7001f90e1 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 22:03:06 +0000 Subject: [PATCH 0510/1116] [CI Pipeline] Released Snapshot version: 5.37.29-alpha-156-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3c6b26f7e..5831c7fe6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.28-alpha-155-SNAPSHOT + 5.37.29-alpha-156-SNAPSHOT UTF-8 From 7cfd327d8f75efc96a1fccbd3dc802348c5fb743 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 22:29:49 +0000 Subject: [PATCH 0511/1116] [CI Pipeline] Released Snapshot version: 5.37.30-alpha-157-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5831c7fe6..97bbfd72f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.29-alpha-156-SNAPSHOT + 5.37.30-alpha-157-SNAPSHOT UTF-8 From 80deb915da9d93974289f56e2cc3fdcbc7e557fa Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 16:52:16 -0600 Subject: [PATCH 0512/1116] show disk usage --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index cbd9e559c..20b408044 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -126,7 +126,12 @@ jobs: name: aws-uid2-deployment-files-${{ steps.version.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error - + + - name: Show disk usage + shell: bash + run: + df + - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main From 5f29f4e0886fd8a19d72b39fd0d2fc595560d91f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 22:53:01 +0000 Subject: [PATCH 0513/1116] [CI Pipeline] Released Snapshot version: 5.37.31-alpha-158-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 97bbfd72f..21c8fe0ab 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.30-alpha-157-SNAPSHOT + 5.37.31-alpha-158-SNAPSHOT UTF-8 From 36f921875c1237a20af2d7340e9432abde22dcb2 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Fri, 14 Jun 2024 17:34:22 -0600 Subject: [PATCH 0514/1116] show disk usage --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 20b408044..fb8dba209 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -130,7 +130,7 @@ jobs: - name: Show disk usage shell: bash run: - df + du -h / - name: Build EUID AWS EIF id: build_euid_eif From cd1da01fca91a33db5639d7bbb5317e397e8330a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 14 Jun 2024 23:35:05 +0000 Subject: [PATCH 0515/1116] [CI Pipeline] Released Snapshot version: 5.37.32-alpha-159-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 21c8fe0ab..8306ce21a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.31-alpha-158-SNAPSHOT + 5.37.32-alpha-159-SNAPSHOT UTF-8 From 48338317bb9bc8e1ae9a5d012f69eb73ad71de31 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sat, 15 Jun 2024 16:26:35 -0600 Subject: [PATCH 0516/1116] show disk usage before build for comparison --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index fb8dba209..298bdbeab 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -113,6 +113,11 @@ jobs: message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} + - name: Show disk usage before build + shell: bash + run: + du -h / + - name: Build UID2 AWS EIF id: build_uid2_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main From ffe3d4f8a4cf9ef994b8d652362220cf3a4ead95 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sat, 15 Jun 2024 22:29:20 +0000 Subject: [PATCH 0517/1116] [CI Pipeline] Released Snapshot version: 5.37.33-alpha-160-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8306ce21a..997214947 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.32-alpha-159-SNAPSHOT + 5.37.33-alpha-160-SNAPSHOT UTF-8 From 883c1654f17ee54504b20aeb6768087b7b606dbd Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sat, 15 Jun 2024 16:44:09 -0600 Subject: [PATCH 0518/1116] try removing all docker container and image after build --- .github/actions/build_aws_eif/action.yaml | 4 ++-- .../publish-aws-nitro-enclave-docker.yaml | 15 +++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 55663e497..ac89af179 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -82,5 +82,5 @@ runs: - name: Cleanup shell: bash run: | - docker stop $(docker ps -a -q) - docker system prune -f + docker rm -vf $(docker ps -aq) + docker rmi -f $(docker images -aq) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 298bdbeab..c9b16b851 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -111,12 +111,7 @@ jobs: with: add: 'pom.xml version.json' message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' - tag: v${{ steps.version.outputs.new_version }} - - - name: Show disk usage before build - shell: bash - run: - du -h / + tag: v${{ steps.version.outputs.new_version }} - name: Build UID2 AWS EIF id: build_uid2_eif @@ -132,10 +127,10 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error - - name: Show disk usage - shell: bash - run: - du -h / +# - name: Show disk usage +# shell: bash +# run: +# du -h / - name: Build EUID AWS EIF id: build_euid_eif From c0d4b286aea6713ad31e344e372294499c87e9f0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sat, 15 Jun 2024 22:45:08 +0000 Subject: [PATCH 0519/1116] [CI Pipeline] Released Snapshot version: 5.37.34-alpha-161-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 997214947..5a2ab983f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.33-alpha-160-SNAPSHOT + 5.37.34-alpha-161-SNAPSHOT UTF-8 From 6dad847d7c28b1d7daea49bba1060772907e9d81 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sat, 15 Jun 2024 23:02:22 +0000 Subject: [PATCH 0520/1116] [CI Pipeline] Released Snapshot version: 5.37.35-alpha-162-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5a2ab983f..f90db59c7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.34-alpha-161-SNAPSHOT + 5.37.35-alpha-162-SNAPSHOT UTF-8 From 126ef6b5a4bcdf3acaa2ca5a108fa9ed61359992 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Sat, 15 Jun 2024 17:16:37 -0600 Subject: [PATCH 0521/1116] update workflow to reference action on my branch --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index c9b16b851..a17476908 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -115,7 +115,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 From 5f2cb4a134598927858b188262b398100fdfbcec Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sat, 15 Jun 2024 23:17:30 +0000 Subject: [PATCH 0522/1116] [CI Pipeline] Released Snapshot version: 5.37.36-alpha-163-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f90db59c7..a3dbf1856 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.35-alpha-162-SNAPSHOT + 5.37.36-alpha-163-SNAPSHOT UTF-8 From 399c4d4d407f4dc15686af7564df11d34c038f1c Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Sat, 15 Jun 2024 23:38:09 -0700 Subject: [PATCH 0523/1116] Respond with 400 instead of 500 when CSTG request validation fails --- .../operator/vertx/UIDOperatorVerticle.java | 4 ++ .../operator/UIDOperatorVerticleTest.java | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 42c6f31bb..c948416ca 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -453,6 +453,10 @@ else if(emailHash != null) { input = InputUtil.normalizePhoneHash(phoneHash); } + if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + return; + } + PrivacyBits privacyBits = new PrivacyBits(); privacyBits.setLegacyBit(); privacyBits.setClientSideTokenGenerate(); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index e900fa96f..c990f7768 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4162,6 +4162,56 @@ void cstgNoActiveKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAlg }); } + @Test + void cstgInvalidEmailHashInput(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + setupCstgBackend("cstg.co.uk"); + setupKeys(true); + String email = "random@unifiedid.com"; + + JsonObject identity = new JsonObject(); + identity.put("email_hash", getSha256(email) + getSha256(email)); + identity.put("optout_check", 1); + Tuple.Tuple2 data = createClientSideTokenGenerateRequestWithPayload(identity, Instant.now().toEpochMilli(), null); + + sendCstg(vertx, + "v2/token/client-generate", + "http://cstg.co.uk", + data.getItem1(), + data.getItem2(), + 400, + testContext, + respJson -> { + assertFalse(respJson.containsKey("body")); + assertEquals("Invalid Identifier", respJson.getString("message")); + testContext.completeNow(); + }); + } + + @Test + void cstgInvalidPhoneHashInput(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + setupCstgBackend("cstg.co.uk"); + setupKeys(true); + String phone = "1234567890"; + + JsonObject identity = new JsonObject(); + identity.put("phone_hash", getSha256(phone) + getSha256(phone)); + identity.put("optout_check", 1); + Tuple.Tuple2 data = createClientSideTokenGenerateRequestWithPayload(identity, Instant.now().toEpochMilli(), null); + + sendCstg(vertx, + "v2/token/client-generate", + "http://cstg.co.uk", + data.getItem1(), + data.getItem2(), + 400, + testContext, + respJson -> { + assertFalse(respJson.containsKey("body")); + assertEquals("Invalid Identifier", respJson.getString("message")); + testContext.completeNow(); + }); + } + private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectClientSideTokenGenerateOptoutResponse) { assertAreClientSideGeneratedTokens(advertisingToken, From 06e664c7830665590f0795f5a8f062bf8ff2daec Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 17 Jun 2024 09:47:02 +1000 Subject: [PATCH 0524/1116] Prevent the adding of env variables to Azure operator --- .../generate-deployment-artifacts.sh | 16 ++++++++++----- scripts/azure-cc/deployment/generate.py | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 scripts/azure-cc/deployment/generate.py diff --git a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh index 375511366..4e6cf97b8 100644 --- a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh +++ b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh @@ -76,9 +76,15 @@ if [[ $? -ne 0 ]]; then exit 1 fi +# Export the policy, update it to turn off allow_environment_variable_dropping, and then insert it into the template +# note that the EnclaveId is generated by generate.py on the raw policy, not the base64 version POLICY_DIGEST_FILE=azure-cc-operator-digest-$VERSION_NUMBER.txt -az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json > ${MANIFEST_DIR}/${POLICY_DIGEST_FILE} -if [[ $? -ne 0 ]]; then - echo "Failed to generate operator template file" - exit 1 -fi +az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json --print-policy > ${OUTPUT_DIR}/policy.base64 +base64 -di < ${OUTPUT_DIR}/policy.base64 > ${OUTPUT_DIR}/generated.rego +sed -i "s#allow_environment_variable_dropping := true#allow_environment_variable_dropping := false#g" ${OUTPUT_DIR}/generated.rego +base64 -w0 < ${OUTPUT_DIR}/generated.rego > ${OUTPUT_DIR}/generated.rego.base64 +python3 ${SCRIPT_DIR}/generate.py ${OUTPUT_DIR}/generated.rego > ${MANIFEST_DIR}/${POLICY_DIGEST_FILE} + +cp ${OUTPUT_DIR}/operator.json ${OUTPUT_DIR}/source.json +jq --arg policy "$(cat ${OUTPUT_DIR}/generated.rego.base64)" '.resources[].properties.confidentialComputeProperties.ccePolicy = $policy' ${OUTPUT_DIR}/source.json > ${OUTPUT_DIR}/operator.json + diff --git a/scripts/azure-cc/deployment/generate.py b/scripts/azure-cc/deployment/generate.py new file mode 100644 index 000000000..07845beac --- /dev/null +++ b/scripts/azure-cc/deployment/generate.py @@ -0,0 +1,20 @@ +import sys +from hashlib import sha256 + +def str_to_sha256(x: str) -> str: + return sha256(x.encode('utf-8')).hexdigest() + +def print_data_sha256(data: str) -> str: + print(str_to_sha256(data)) + +def print_data_sha256_stripped(data: str) -> str: + print(str_to_sha256(data.strip())) + +def main(): + with open(sys.argv[1], 'r') as file: + data = file.read() + + print_data_sha256(data) + +if __name__ == '__main__': + main() From b2435284acd23a207dcf17c3fa3bb71afeeccc95 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Sun, 16 Jun 2024 23:49:55 +0000 Subject: [PATCH 0525/1116] [CI Pipeline] Released Snapshot version: 5.37.16-alpha-109-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0754e7e4b..afe4c3796 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.15 + 5.37.16-alpha-109-SNAPSHOT UTF-8 From 65c8d155525676d8676e630df4d92e98b67485d6 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 17 Jun 2024 10:19:48 +1000 Subject: [PATCH 0526/1116] Removed the temp files from the output --- .../deployment/generate-deployment-artifacts.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh index 4e6cf97b8..4dd4252c6 100644 --- a/scripts/azure-cc/deployment/generate-deployment-artifacts.sh +++ b/scripts/azure-cc/deployment/generate-deployment-artifacts.sh @@ -79,12 +79,12 @@ fi # Export the policy, update it to turn off allow_environment_variable_dropping, and then insert it into the template # note that the EnclaveId is generated by generate.py on the raw policy, not the base64 version POLICY_DIGEST_FILE=azure-cc-operator-digest-$VERSION_NUMBER.txt -az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json --print-policy > ${OUTPUT_DIR}/policy.base64 -base64 -di < ${OUTPUT_DIR}/policy.base64 > ${OUTPUT_DIR}/generated.rego -sed -i "s#allow_environment_variable_dropping := true#allow_environment_variable_dropping := false#g" ${OUTPUT_DIR}/generated.rego -base64 -w0 < ${OUTPUT_DIR}/generated.rego > ${OUTPUT_DIR}/generated.rego.base64 -python3 ${SCRIPT_DIR}/generate.py ${OUTPUT_DIR}/generated.rego > ${MANIFEST_DIR}/${POLICY_DIGEST_FILE} +az confcom acipolicygen --approve-wildcards --template-file ${OUTPUT_DIR}/operator.json --print-policy > ${INPUT_DIR}/policy.base64 +base64 -di < ${INPUT_DIR}/policy.base64 > ${INPUT_DIR}/generated.rego +sed -i "s#allow_environment_variable_dropping := true#allow_environment_variable_dropping := false#g" ${INPUT_DIR}/generated.rego +base64 -w0 < ${INPUT_DIR}/generated.rego > ${INPUT_DIR}/generated.rego.base64 +python3 ${SCRIPT_DIR}/generate.py ${INPUT_DIR}/generated.rego > ${MANIFEST_DIR}/${POLICY_DIGEST_FILE} -cp ${OUTPUT_DIR}/operator.json ${OUTPUT_DIR}/source.json -jq --arg policy "$(cat ${OUTPUT_DIR}/generated.rego.base64)" '.resources[].properties.confidentialComputeProperties.ccePolicy = $policy' ${OUTPUT_DIR}/source.json > ${OUTPUT_DIR}/operator.json +cp ${OUTPUT_DIR}/operator.json ${INPUT_DIR}/source.json +jq --arg policy "$(cat ${INPUT_DIR}/generated.rego.base64)" '.resources[].properties.confidentialComputeProperties.ccePolicy = $policy' ${INPUT_DIR}/source.json > ${OUTPUT_DIR}/operator.json From a62593fa85a7149393838a2ac93c0a7a5d65818c Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 17 Jun 2024 00:22:59 +0000 Subject: [PATCH 0527/1116] [CI Pipeline] Released Snapshot version: 5.37.17-alpha-110-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index afe4c3796..8366cc540 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.16-alpha-109-SNAPSHOT + 5.37.17-alpha-110-SNAPSHOT UTF-8 From d2575840303bc07462362048ac5309a863255fe0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 17 Jun 2024 01:01:10 +0000 Subject: [PATCH 0528/1116] [CI Pipeline] Released Patch version: 5.37.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8366cc540..2f621d1b8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.17-alpha-110-SNAPSHOT + 5.37.22 UTF-8 From fc22065f194ce74b193f7c18d1feec592e0e4608 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Mon, 17 Jun 2024 16:54:29 +1000 Subject: [PATCH 0529/1116] UID2-3366 Build ami in operator repo (#610) * Adding packer files to build ami * Build euid for testing * Change path to action * added git checkout * Try download artifact * change name of artifact * Testing file name * download all * Added github_token input * Pass token to action * add file name * add AWS role request * move role request to action * add write id-token * change working folder * adding some logging * move the files * create directory first * setup packer * added anisble to plugins * changed vpc * [CI Pipeline] Released Patch version: 5.32.4 * [CI Pipeline] Released Patch version: 5.32.10 * [CI Pipeline] Released Patch version: 5.32.12 * [CI Pipeline] Released Patch version: 5.32.16 * [CI Pipeline] Released Patch version: 5.32.19 * [CI Pipeline] Released Patch version: 5.32.22 * [CI Pipeline] Released Patch version: 5.32.25 * [CI Pipeline] Released Patch version: 5.32.28 * Adding the ability to diable CSTG key * Resolve conflicts * Update actions and workflow to match the latest version in aws-operator-building repo * Fix conflicts with main * Update working-directory to ./scripts/aws/uid2-operator-ami * Make workflow run on ubuntu instead of self-host runner * Fix paths for actions * Use the correct token credential * Add env for `repo_owner` and `repo_name` * Config aws auth * Add steps to build EUID and collect artifacts * Add EUID AWS credentials * Revert changes to match main * Specify ansible version to 9.6.1 * Move role and region to env variable * Change default value for `save_ami` to `true` * Fix naming for AMI artifacts * Add ls statement to print out files in folder * Remove pre and post cleanup * Remove unused `DOWNLOAD_PATH_OLD` * Change custom branch to main --------- Co-authored-by: Thomas Manson Co-authored-by: Release Workflow Co-authored-by: Cody Constine --- .github/actions/build_ami/action.yaml | 191 ++++++++++++++++ .../download_release_artifact/action.yaml | 83 +++++++ .github/workflows/build-uid2-ami.yaml | 126 +++++++++++ pom.xml | 2 +- .../uid2-operator-ami/ansible/playbook.yml | 207 ++++++++++++++++++ scripts/aws/uid2-operator-ami/build.pkr.hcl | 19 ++ .../aws/uid2-operator-ami/euid.pkrvars.hcl | 7 + scripts/aws/uid2-operator-ami/plugins.pkr.hcl | 12 + scripts/aws/uid2-operator-ami/source.pkr.hcl | 39 ++++ .../aws/uid2-operator-ami/uid2.pkrvars.hcl | 7 + scripts/aws/uid2-operator-ami/vars.pkr.hcl | 72 ++++++ 11 files changed, 764 insertions(+), 1 deletion(-) create mode 100644 .github/actions/build_ami/action.yaml create mode 100644 .github/actions/download_release_artifact/action.yaml create mode 100644 .github/workflows/build-uid2-ami.yaml create mode 100644 scripts/aws/uid2-operator-ami/ansible/playbook.yml create mode 100644 scripts/aws/uid2-operator-ami/build.pkr.hcl create mode 100644 scripts/aws/uid2-operator-ami/euid.pkrvars.hcl create mode 100644 scripts/aws/uid2-operator-ami/plugins.pkr.hcl create mode 100644 scripts/aws/uid2-operator-ami/source.pkr.hcl create mode 100644 scripts/aws/uid2-operator-ami/uid2.pkrvars.hcl create mode 100644 scripts/aws/uid2-operator-ami/vars.pkr.hcl diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml new file mode 100644 index 000000000..83e16522f --- /dev/null +++ b/.github/actions/build_ami/action.yaml @@ -0,0 +1,191 @@ +name: Build AMI +description: Builds the AMI for AWS private operators + +inputs: + identity_scope: + description: The identity scope [uid2, euid] + required: true + github_token: + description: The GITHUB token to use to get the EIF + required: true + eif_repo_owner: + description: The owner of the EIF repo + required: true + eif_repo_name: + description: The name of the EIF repo + required: true + operator_release: + description: The operator release that has the EIF to use + default: '' + operator_branch: + description: The Operator Branch to build from + default: main + operator_run_number: + description: The Operator run number for artifacts. Ignored if Operator Release is given + save_ami: + description: Save the AMIs as a build artifact. + default: true + uid2_aws_role: + description: The AWS role to assume for UID2 + required: true + uid2_aws_region: + description: The UID2 AWS region to upload AMI to + required: true + euid_aws_role: + description: The AWS role to assume for EUID + required: true + euid_aws_region: + description: The EUID AWS region to upload AMI to + required: true + +outputs: + version_number: + description: The version number set in IABTechLab/uid2-operator pom.xml. + value: ${{ steps.versionNumber.outputs.version_number }} + +runs: + using: "composite" + + steps: + - name: Show Context + shell: bash + run: | + printenv + echo "$GITHUB_CONTEXT" + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + + - name: Checkout full history + uses: actions/checkout@v4 + + - name: Get EIF for Release ${{ inputs.operator_release }} + uses: IABTechLab/uid2-operator/.github/actions/download_release_artifact@main + if: ${{ inputs.operator_release != '' }} + with: + github_token: ${{ inputs.github_token }} + repo_owner: ${{ inputs.eif_repo_owner }} + repo_name: ${{ inputs.eif_repo_name }} + release_name: ${{ inputs.operator_release }} + artifact_name: aws-${{ inputs.identity_scope }}-deployment-files + folder: ./scripts/aws/uid2-operator-ami/artifacts + + - name: Get EIF for Run ${{ inputs.operator_run_number }} + id: get_eif_for_run + uses: actions/download-artifact@v4 + if: ${{ inputs.operator_release == '' }} + with: + github_token: ${{ inputs.github_token }} + repo: IABTechLab/uid2-operator + name: 'aws-${{ inputs.identity_scope }}-deployment-files-.*' + name_is_regexp: true + run_id: ${{ inputs.operator_run_number }} + skip_unpack: true + path: ./download/artifacts + + - name: Unzip artifacts + if: ${{ inputs.operator_release == '' }} + shell: bash + run: | + ARTIFACTS='${{ steps.get_eif_for_run.outputs.artifacts }}' + FILE=$(echo $ARTIFACTS | jq -r '.[0].name') + unzip -o -d ./scripts/aws/uid2-operator-ami/artifacts $FILE.zip + rm $FILE.zip + + - name: Configure UID2 AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + if: ${{ inputs.identity_scope == 'uid2' }} + with: + aws-region: ${{ inputs.uid2_aws_region }} + role-to-assume: ${{ inputs.uid2_aws_role }} + + - name: Configure EUID AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + if: ${{ inputs.identity_scope == 'euid' }} + with: + aws-region: ${{ inputs.euid_aws_region }} + role-to-assume: ${{ inputs.euid_aws_role }} + + - name: Show AWS Identity + shell: bash + run: | + aws sts get-caller-identity + + - name: Get version number + id: versionNumber + shell: bash + working-directory: ./scripts/aws/uid2-operator-ami + run: | + ls -al + VERSION_NUMBER=$(cat ./artifacts/version_number.txt) + echo "VERSION_NUMBER=$VERSION_NUMBER" >> $GITHUB_OUTPUT + echo $VERSION_NUMBER + + - name: Setup Packer + id: setup-packer + uses: hashicorp/setup-packer@main + + - name: Create AMI + shell: bash + working-directory: ./scripts/aws/uid2-operator-ami + run: | + ls -al + TIMESTAMP=$(date +%s) + echo "TIMESTAMP=$TIMESTAMP" >> $GITHUB_OUTPUT + packer init . + packer build \ + -var "version=${{ steps.versionNumber.outputs.VERSION_NUMBER }}" \ + -var "timestamp=$TIMESTAMP" \ + -var-file="${{ inputs.identity_scope }}.pkrvars.hcl" \ + -debug \ + . + + - name: Extract AMI ID + id: extractAmiId + shell: bash + working-directory: ./scripts/aws/uid2-operator-ami + run: | + AMI_ID=$(jq -r '.builds[-1].artifact_id' manifest.json | cut -d ":" -f2) + echo "AMI_ID=$AMI_ID" >> $GITHUB_OUTPUT + echo $AMI_ID + + - name: Persist UID2 enclave and AMI IDs + if: ${{ inputs.identity_scope == 'uid2' }} + shell: bash + working-directory: ./scripts/aws/uid2-operator-ami + run: | + touch uid2_AMI_measurement.txt + echo "Enclave ID: $(cat ./artifacts/pcr0.txt)" >> uid2_AMI_measurement.txt + echo "AMI ID: " ${{ steps.extractAmiId.outputs.AMI_ID }} >> uid2_AMI_measurement.txt + echo "uid2_AMI_measurement.txt Contents:" + cat uid2_AMI_measurement.txt + ls -al + + - name: Copy AMI to us-east-1 + id: euidCopyAmi + if: ${{ inputs.identity_scope == 'euid' }} + shell: bash + working-directory: ./scripts/aws/uid2-operator-ami + run: | + US_EAST_AMI_ID=$(aws ec2 copy-image --region us-east-1 --source-region eu-central-1 --source-image-id ${{ steps.extractAmiId.outputs.AMI_ID }} --name euid-operator-${{ steps.versionNumber.outputs.VERSION_NUMBER }}-${{ steps.createAMI.outputs.TIMESTAMP }} --output text) + echo "US_EAST_1_AMI_ID=$US_EAST_AMI_ID" >> $GITHUB_OUTPUT + echo $US_EAST_AMI_ID + + - name: Persist EUID enclave and AMI IDs + if: ${{ inputs.identity_scope == 'euid' }} + shell: bash + working-directory: ./scripts/aws/uid2-operator-ami + run: | + touch euid_AMI_measurement.txt + echo "Enclave ID: $(cat ./artifacts/pcr0.txt)" >> euid_AMI_measurement.txt + echo "eu-central-1 AMI ID:" ${{ steps.extractAmiId.outputs.AMI_ID }} >> euid_AMI_measurement.txt + echo "us-east-1 AMI ID:" ${{ steps.euidCopyAmi.outputs.US_EAST_1_AMI_ID }} >> euid_AMI_measurement.txt + echo "euid_AMI_measurement.txt contents" + cat euid_AMI_measurement.txt + ls -al + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: ${{ inputs.save_ami == 'true' }} + with: + name: ${{ inputs.identity_scope }}_AMI_measurement + path: ./scripts/aws/uid2-operator-ami/${{ inputs.identity_scope }}_AMI_measurement.txt diff --git a/.github/actions/download_release_artifact/action.yaml b/.github/actions/download_release_artifact/action.yaml new file mode 100644 index 000000000..13e38aafd --- /dev/null +++ b/.github/actions/download_release_artifact/action.yaml @@ -0,0 +1,83 @@ +name: Download Release Artifact +description: Downloads an artifact from a release + +inputs: + github_token: + description: The GITHUB_TOKEN to use for the target repo + required: false + repo_owner: + description: The owner of the target repo + required: true + repo_name: + description: The name of the target repo + required: true + release_name: + description: The release name that contains the aritfact + required: true + artifact_name: + description: The name of the artifact. Can be a partial name + required: true + folder: + description: The folder to download the artifact to and then unpack + required: true + +runs: + using: "composite" + + steps: + - name: Get Artifact Ids + id: get_asset_id + uses: actions/github-script@v7 + with: + github-token: ${{ inputs.github_token }} + result-encoding: string + script: | + let allReleases = await github.rest.repos.listReleases({ + owner: '${{ inputs.repo_owner }}', + repo: '${{ inputs.repo_name }}' + }) + + assetUrl = "" + let matchedReleases = allReleases.data.filter((release) => { + return release.name == "${{ inputs.release_name }}" + }) + if (matchedReleases.length == 0) { + core.setFailed('Unable to find release: ' + '${{ inputs.release_name }}' ); + } else { + let matchedRelease = matchedReleases[0]; + let releaseId = matchedRelease.id; + console.log('Release Id:' + releaseId); + + let assets = matchedRelease.assets.filter((asset) => { + return asset.name.includes('${{ inputs.artifact_name }}') + }); + if (assets.length == 0) { + core.setFailed('Unable to find asset in release'); + } else { + let asset = assets[0]; + console.log('Asset:'); + console.log(asset); + assetUrl = asset.url + } + + return assetUrl + } + + - name: Download Assets + shell: bash + run: | + echo 'Asset URL: ${{ steps.get_asset_id.outputs.result }}' + + mkdir -p ./${{ inputs.folder }} + DOWNLOAD_PATH=${{ steps.get_asset_id.outputs.result }} + echo $DOWNLOAD_PATH + curl -L -H "Accept: application/octet-stream" \ + -H "Authorization: Bearer ${{ inputs.github_token }}" \ + -o "./${{ inputs.folder }}/${{ inputs.artifact_name }}.zip" \ + $DOWNLOAD_PATH + + - name: Unzip artifacts + shell: bash + run: | + unzip -o -d './${{ inputs.folder }}' './${{ inputs.folder }}/${{ inputs.artifact_name }}.zip' + rm './${{ inputs.folder }}/${{ inputs.artifact_name }}.zip' diff --git a/.github/workflows/build-uid2-ami.yaml b/.github/workflows/build-uid2-ami.yaml new file mode 100644 index 000000000..7a202a5c8 --- /dev/null +++ b/.github/workflows/build-uid2-ami.yaml @@ -0,0 +1,126 @@ +name: Build UID2 and EUID AMIs +run-name: Build UID2 and EUID AMIs for Operator Release ${{ inputs.operator_release }} by @${{ github.actor }} +on: + workflow_dispatch: + inputs: + operator_release: + description: The Operator Release number that built the EIF files to use + type: string + operator_run_number: + description: The Operator run number. Ignored if Release Number specified. + type: string + operator_branch: + description: The branch of Operator to use. + type: string + default: main + save_ami: + description: Save the AMIs as a build artifact. + type: boolean + required: false + default: true + +env: + REPO_OWNER: IABTechLab + REPO_NAME: uid2-operator + UID2_AWS_ROLE: arn:aws:iam::475720075663:role/github-runner-operator-runner + UID2_AWS_REGION: us-east-2 + EUID_AWS_ROLE: arn:aws:iam::618285103646:role/github-runner-operator-runner + EUID_AWS_REGION: eu-central-1 + +jobs: + buildUID2: + name: UID2 Operator AMI + runs-on: ubuntu-latest + permissions: + id-token: write + outputs: + version_number: ${{ steps.buildAMI.outputs.version_number }} + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Build UID2 Operator AMI + id: buildAMI + uses: IABTechLab/uid2-operator/.github/actions/build_ami@main + with: + identity_scope: uid2 + eif_repo_owner: ${{ env.REPO_OWNER }} + eif_repo_name: ${{ env.REPO_NAME }} + github_token: ${{ github.token }} + operator_release: ${{ inputs.operator_release }} + operator_run_number: ${{ inputs.operator_run_number }} + operator_branch: ${{ inputs.operator_branch }} + save_ami: ${{ inputs.save_ami }} + uid2_aws_role: ${{ env.UID2_AWS_ROLE }} + uid2_aws_region: ${{ env.UID2_AWS_REGION }} + euid_aws_role: ${{ env.EUID_AWS_ROLE }} + euid_aws_region: ${{ env.EUID_AWS_REGION }} + + buildEUID: + name: EUID Operator AMI + runs-on: ubuntu-latest + permissions: + id-token: write + outputs: + version_number: ${{ steps.buildAMI.outputs.version_number }} + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Pre-cleanup + shell: bash + working-directory: ${{ github.workspace }} + run: | + echo "Cleaning up previous run" + sudo rm -rf * || true + docker stop $(docker ps -aq) || true + docker rm $(docker ps -aq) || true + docker rmi $(docker images -q) || true + + - name: Build EUID Operator AMI + id: buildAMI + uses: IABTechLab/uid2-operator/.github/actions/build_ami@main + with: + identity_scope: euid + eif_repo_owner: ${{ env.REPO_OWNER }} + eif_repo_name: ${{ env.REPO_NAME }} + github_token: ${{ github.token }} + operator_release: ${{ inputs.operator_release }} + operator_run_number: ${{ inputs.operator_run_number }} + operator_branch: ${{ inputs.operator_branch }} + save_ami: ${{ inputs.save_ami }} + uid2_aws_role: ${{ env.UID2_AWS_ROLE }} + uid2_aws_region: ${{ env.UID2_AWS_REGION }} + euid_aws_role: ${{ env.EUID_AWS_ROLE }} + euid_aws_region: ${{ env.EUID_AWS_REGION }} + + collectAllArtifacts: + name: Collect All Artifacts + if: ${{ inputs.save_ami }} + runs-on: ubuntu-latest + needs: [buildUID2, buildEUID] + steps: + - name: Download UID2 artifacts + uses: actions/download-artifact@v4 + with: + name: uid2_AMI_measurement + path: ./artifacts + + - name: Download EUID artifacts + uses: actions/download-artifact@v4 + with: + name: euid_AMI_measurement + path: ./artifacts + + - name: Delete staging artifacts + uses: geekyeggo/delete-artifact@v5 + with: + name: | + uid2_AMI_measurement + euid_AMI_measurement + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: uid2-operator-release-${{ needs.buildUID2.outputs.version_number }}-aws + path: ./artifacts/ diff --git a/pom.xml b/pom.xml index 2f621d1b8..0754e7e4b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.22 + 5.37.15 UTF-8 diff --git a/scripts/aws/uid2-operator-ami/ansible/playbook.yml b/scripts/aws/uid2-operator-ami/ansible/playbook.yml new file mode 100644 index 000000000..f80f5f013 --- /dev/null +++ b/scripts/aws/uid2-operator-ami/ansible/playbook.yml @@ -0,0 +1,207 @@ +--- +- name: Test Ansible playbook + hosts: all + connection: ssh + gather_facts: yes + become: yes + become_user: root + become_method: sudo + + tasks: + - name: Update all base packages + ansible.builtin.yum: + update_cache: yes + name: '*' + state: latest + + - name: Install Netcat + ansible.builtin.yum: + name: nmap-ncat + state: latest + + - name: Create etc/uid2operator directory + ansible.builtin.file: + path: /etc/uid2operator + state: directory + + - name: Create opt/uid2operator directory + ansible.builtin.file: + path: /opt/uid2operator + state: directory + + - name: vsock-proxy config + ansible.builtin.copy: + src: /tmp/artifacts/proxies.host.yaml + dest: /etc/uid2operator/proxy.yaml + remote_src: yes + + - name: Install vsock-proxy + ansible.builtin.copy: + src: /tmp/artifacts/vsockpx + dest: /usr/bin/vsockpx + remote_src: yes + + - name: Make vsock-proxy executable + ansible.builtin.file: + path: /usr/bin/vsockpx + mode: '0755' + + - name: Install starter script + ansible.builtin.copy: + src: /tmp/artifacts/start.sh + dest: /opt/uid2operator/start.sh + remote_src: yes + + - name: Make starter script executable + ansible.builtin.file: + path: /opt/uid2operator/start.sh + mode: '0755' + + - name: Install stopper script + ansible.builtin.copy: + src: /tmp/artifacts/stop.sh + dest: /opt/uid2operator/stop.sh + remote_src: yes + + - name: Make starter script executable + ansible.builtin.file: + path: /opt/uid2operator/stop.sh + mode: '0755' + + - name: Install Operator EIF + ansible.builtin.copy: + src: /tmp/artifacts/uid2operator.eif + dest: /opt/uid2operator/uid2operator.eif + remote_src: yes + + - name: Install Identity Scope + ansible.builtin.copy: + src: /tmp/artifacts/identity_scope.txt + dest: /opt/uid2operator/identity_scope.txt + remote_src: yes + + - name: Dante config + ansible.builtin.copy: + src: /tmp/artifacts/sockd.conf + dest: /etc/sockd.conf + remote_src: yes + + - name: Install Dante + ansible.builtin.copy: + src: /tmp/artifacts/sockd + dest: /usr/bin/sockd + remote_src: yes + + - name: Copy Syslog package + ansible.builtin.copy: + src: /tmp/artifacts/syslog-ng-4.6.0-1.el7.x86_64.rpm + dest: /opt/uid2operator/syslog-ng-4.6.0-1.el7.x86_64.rpm + remote_src: yes + + - name: Copy Syslog public key + ansible.builtin.copy: + src: /tmp/artifacts/syslog-ng-pubkey.gpg + dest: /opt/uid2operator/syslog-ng-pubkey.gpg + remote_src: yes + + - name: Make sockd executable + ansible.builtin.file: + path: /usr/bin/sockd + mode: '0755' + + - name: Install Operator service + ansible.builtin.copy: + src: /tmp/artifacts/uid2operator.service + dest: /etc/systemd/system/uid2operator.service + remote_src: yes + + - name: Ensure nitro-cli is installed to the latest version + ansible.builtin.command: amazon-linux-extras install aws-nitro-enclaves-cli + + - name: Ensure nitro enclave allocator is enabled at boot + ansible.builtin.systemd: + name: nitro-enclaves-allocator.service + enabled: yes + + - name: Update nitro enclave CPU allocation + ansible.builtin.command: 'sed -r "s/^(\s*cpu_count\s*:\s*).*/\16/" -i /etc/nitro_enclaves/allocator.yaml' + + - name: Update nitro enclave memory allocation + ansible.builtin.command: 'sed -r "s/^(\s*memory_mib\s*:\s*).*/\124576/" -i /etc/nitro_enclaves/allocator.yaml' + + # - name: Apply Nitro Enclave allocator change + # ansible.builtin.systemd: + # name: nitro-enclaves-allocator.service + # state: restarted + - name: Install EPEL + ansible.builtin.command: amazon-linux-extras install epel + + - name: Install ivykis + ansible.builtin.yum: + name: ivykis-0.36.2-2.el7 + state: present + + - name: Install libnet + ansible.builtin.yum: + name: libnet-1.1.6-7.amzn2.0.2 + state: present + + - name: Register Public key + ansible.builtin.command: rpmkeys --import /opt/uid2operator/syslog-ng-pubkey.gpg + + - name: Install package + ansible.builtin.command: rpm -U /opt/uid2operator/syslog-ng-4.6.0-1.el7.x86_64.rpm + + - name: unregister Public key + ansible.builtin.command: rpm -e gpg-pubkey-c57846f4-65a8cf14 + + - name: syslog-ng config + ansible.builtin.copy: + src: /tmp/artifacts/syslog-ng-server.conf + dest: /etc/syslog-ng/syslog-ng.conf + remote_src: yes + + - name: logrotate config + ansible.builtin.copy: + src: /tmp/artifacts/operator-logrotate.conf + dest: /etc/logrotate.d/operator-logrotate.conf + remote_src: yes + + - name: Run logrotate under cron.d + ansible.builtin.copy: + src: /tmp/artifacts/logrotate + dest: /etc/cron.d/logrotate + mode: 0644 + remote_src: yes + + - name: Ensure rsyslog is disabled at boot + ansible.builtin.systemd: + name: rsyslog + state: stopped + enabled: false + + - name: Ensure syslog-ng is enabled at boot + ansible.builtin.systemd: + name: syslog-ng + state: started + enabled: true + + - name: Ensure uid2 operator is enabled at boot + ansible.builtin.systemd: + name: uid2operator.service + enabled: yes + + - name: Clean up tmp files + file: + path: /tmp/artifacts + state: absent + + - name: Clean up ec2_user SSH authorized keys file + file: + path: /home/ec2-user/.ssh/authorized_keys + state: absent + + - name: Clean up root SSH authorized keys file + file: + path: /root/.ssh/authorized_keys + state: absent diff --git a/scripts/aws/uid2-operator-ami/build.pkr.hcl b/scripts/aws/uid2-operator-ami/build.pkr.hcl new file mode 100644 index 000000000..36d43390e --- /dev/null +++ b/scripts/aws/uid2-operator-ami/build.pkr.hcl @@ -0,0 +1,19 @@ +build { + sources = ["source.amazon-ebs.linux"] + + provisioner "file" { + source = "./artifacts" + destination = "/tmp" + } + + provisioner "ansible" { + playbook_file = "./ansible/playbook.yml" + extra_arguments = [ "--scp-extra-args", "'-O'", "--version", "9.6.1" ] + } + + post-processor "manifest" { + output = "manifest.json" + strip_path = true + } +} + diff --git a/scripts/aws/uid2-operator-ami/euid.pkrvars.hcl b/scripts/aws/uid2-operator-ami/euid.pkrvars.hcl new file mode 100644 index 000000000..7bf10b8ce --- /dev/null +++ b/scripts/aws/uid2-operator-ami/euid.pkrvars.hcl @@ -0,0 +1,7 @@ +region = "eu-central-1" +identity_scope = "euid" +subnet_id = "subnet-0edbf47b073de1c79" +vpc_id = "vpc-065000fb9082c6a90" +ami_ou_arns = [ + "arn:aws:organizations::155852253738:ou/o-v1vmbc3c9h/ou-96c8-2vbyb92d" +] diff --git a/scripts/aws/uid2-operator-ami/plugins.pkr.hcl b/scripts/aws/uid2-operator-ami/plugins.pkr.hcl new file mode 100644 index 000000000..ee414c421 --- /dev/null +++ b/scripts/aws/uid2-operator-ami/plugins.pkr.hcl @@ -0,0 +1,12 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.0.0" + source = "github.com/hashicorp/amazon" + } + ansible = { + version = "~> 1" + source = "github.com/hashicorp/ansible" + } + } +} diff --git a/scripts/aws/uid2-operator-ami/source.pkr.hcl b/scripts/aws/uid2-operator-ami/source.pkr.hcl new file mode 100644 index 000000000..b12766b0e --- /dev/null +++ b/scripts/aws/uid2-operator-ami/source.pkr.hcl @@ -0,0 +1,39 @@ +source "amazon-ebs" "linux" { + + # source parameters + source_ami_filter { + filters = { + name = "amzn2-ami-hvm-*-x86_64-ebs" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["amazon"] + } + + # disable ami creation for testing + # skip_create_ami = true + + # instance parameters + ami_name = local.ami_name + ami_ou_arns = var.ami_ou_arns + instance_type = var.instance_type + region = var.region + subnet_id = var.subnet_id + vpc_id = var.vpc_id + + # connection parameters + communicator = var.communicator + ssh_username = var.ssh_username + ssh_interface = var.ssh_interface + iam_instance_profile = var.iam_instance_profile + + tags = { + Environment = var.env + Service = var.service + Version = var.version + Name = local.ami_name + Build = "packer" + BuildTime = var.timestamp + } +} diff --git a/scripts/aws/uid2-operator-ami/uid2.pkrvars.hcl b/scripts/aws/uid2-operator-ami/uid2.pkrvars.hcl new file mode 100644 index 000000000..968ec4042 --- /dev/null +++ b/scripts/aws/uid2-operator-ami/uid2.pkrvars.hcl @@ -0,0 +1,7 @@ +region = "us-east-1" +identity_scope = "uid2" +subnet_id = "subnet-03a2ae9b83ee4a1be" +vpc_id = "vpc-056adf611333ebf06" +ami_ou_arns = [ + "arn:aws:organizations::155852253738:ou/o-v1vmbc3c9h/ou-96c8-2vbyb92d" +] diff --git a/scripts/aws/uid2-operator-ami/vars.pkr.hcl b/scripts/aws/uid2-operator-ami/vars.pkr.hcl new file mode 100644 index 000000000..a76f6dcdc --- /dev/null +++ b/scripts/aws/uid2-operator-ami/vars.pkr.hcl @@ -0,0 +1,72 @@ +variable "env" { + description = "distinct environment/stage name" + default = "production" +} + +variable "identity_scope" { + description = "The scope of the operator. uid2 or euid" + default = "uid2" +} + +variable "service" { + description = "distinct name for the service" + default = "operator" +} + +variable "region" { + description = "AWS region name" + default = "us-east-1" +} + +variable "instance_type" { + description = "instance type to build on" + default = "m5.2xlarge" +} + +variable "vpc_id" { + description = "vpc id for instance creation" +} + +variable "subnet_id" { + description = "subnet id for instance creation" +} + +variable "communicator" { + description = "communication method used for the instance" + default = "ssh" +} + +variable "ssh_username" { + description = "ssh username for packer to use for provisioning" + default = "ec2-user" +} + +variable "ssh_interface" { + description = "ssh interface for packer to use for provisioning" + default = "session_manager" +} + +variable "iam_instance_profile" { + description = "IAM instance profile to attach to AMI instance for SSM" + default = "aws-operator-self-hosted-runner.target" +} + +variable "version" { + description = "release version" +} + +variable "ami_ou_arns" { + description = "A list of Amazon Resource Names (ARN) of AWS Organizations that have access to launch the resulting AMI(s)." + type = list(string) +} + +variable "timestamp" { + description = "unique timestamp" +} + +locals { + identifier = "${var.identity_scope}-${var.service}" + version = "${var.version}" + + ami_name = "${local.identifier}-${local.version}-${var.timestamp}" +} From ae1b0bca131c6c3efe8a2f45d46df96f55c7473f Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 12:32:41 -0600 Subject: [PATCH 0530/1116] update workflow to reference action on my branch --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index a17476908..944b562c2 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -134,7 +134,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 6853f01ca0e29cf96a733f102bc30cafd69b9dc5 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 17 Jun 2024 18:48:52 +0000 Subject: [PATCH 0531/1116] [CI Pipeline] Released Snapshot version: 5.37.37-alpha-165-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a3dbf1856..2c6b94aea 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.36-alpha-163-SNAPSHOT + 5.37.37-alpha-165-SNAPSHOT UTF-8 From a526de455f789c967bf90db0746a85df1449425a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:08:49 -0600 Subject: [PATCH 0532/1116] _ -> - --- .github/actions/build_ami/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index 83e16522f..ebc8776f8 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -78,7 +78,7 @@ runs: repo: IABTechLab/uid2-operator name: 'aws-${{ inputs.identity_scope }}-deployment-files-.*' name_is_regexp: true - run_id: ${{ inputs.operator_run_number }} + run-id: ${{ inputs.operator_run_number }} skip_unpack: true path: ./download/artifacts From fa3644c2e8754bfb94a415de0e29e3a7e1c0a1e2 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:11:10 -0600 Subject: [PATCH 0533/1116] use action on branch --- .github/workflows/build-uid2-ami.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-uid2-ami.yaml b/.github/workflows/build-uid2-ami.yaml index 7a202a5c8..6db8fc68c 100644 --- a/.github/workflows/build-uid2-ami.yaml +++ b/.github/workflows/build-uid2-ami.yaml @@ -41,7 +41,7 @@ jobs: - name: Build UID2 Operator AMI id: buildAMI - uses: IABTechLab/uid2-operator/.github/actions/build_ami@main + uses: IABTechLab/uid2-operator/.github/actions/build_ami@ian-UID2-3362-upgrade-java-21 with: identity_scope: uid2 eif_repo_owner: ${{ env.REPO_OWNER }} From 82d3f26af3c6470016437ef24ca879fe5465e278 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:17:40 -0600 Subject: [PATCH 0534/1116] update inputs for download --- .github/actions/build_ami/action.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index ebc8776f8..c9ecd9a50 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -74,12 +74,10 @@ runs: uses: actions/download-artifact@v4 if: ${{ inputs.operator_release == '' }} with: - github_token: ${{ inputs.github_token }} - repo: IABTechLab/uid2-operator - name: 'aws-${{ inputs.identity_scope }}-deployment-files-.*' - name_is_regexp: true + github-token: ${{ inputs.github_token }} + repository: IABTechLab/uid2-operator + pattern: 'aws-${{ inputs.identity_scope }}-deployment-files-*' run-id: ${{ inputs.operator_run_number }} - skip_unpack: true path: ./download/artifacts - name: Unzip artifacts From bcaeecddf20c12952f2c05ed503fef9431eb0e11 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:26:50 -0600 Subject: [PATCH 0535/1116] already unzipped? --- .github/actions/build_ami/action.yaml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index c9ecd9a50..da8cc0539 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -78,16 +78,7 @@ runs: repository: IABTechLab/uid2-operator pattern: 'aws-${{ inputs.identity_scope }}-deployment-files-*' run-id: ${{ inputs.operator_run_number }} - path: ./download/artifacts - - - name: Unzip artifacts - if: ${{ inputs.operator_release == '' }} - shell: bash - run: | - ARTIFACTS='${{ steps.get_eif_for_run.outputs.artifacts }}' - FILE=$(echo $ARTIFACTS | jq -r '.[0].name') - unzip -o -d ./scripts/aws/uid2-operator-ami/artifacts $FILE.zip - rm $FILE.zip + path: ./scripts/aws/uid2-operator-ami/artifacts - name: Configure UID2 AWS credentials uses: aws-actions/configure-aws-credentials@v4 From 3643019ac1b36fe66f08d44dbe6c863020f41277 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:29:49 -0600 Subject: [PATCH 0536/1116] try without .zip extension --- .github/actions/build_ami/action.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index da8cc0539..4403bed74 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -78,7 +78,16 @@ runs: repository: IABTechLab/uid2-operator pattern: 'aws-${{ inputs.identity_scope }}-deployment-files-*' run-id: ${{ inputs.operator_run_number }} - path: ./scripts/aws/uid2-operator-ami/artifacts + path: ./download/artifacts + + - name: Unzip artifacts + if: ${{ inputs.operator_release == '' }} + shell: bash + run: | + ARTIFACTS='${{ steps.get_eif_for_run.outputs.artifacts }}' + FILE=$(echo $ARTIFACTS | jq -r '.[0].name') + unzip -o -d ./scripts/aws/uid2-operator-ami/artifacts $FILE + rm $FILE - name: Configure UID2 AWS credentials uses: aws-actions/configure-aws-credentials@v4 From f0c9570eefd377acc1ad8b93512f1b70439e70b4 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:34:22 -0600 Subject: [PATCH 0537/1116] set merge multiple true --- .github/actions/build_ami/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index 4403bed74..3f48874a2 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -79,6 +79,7 @@ runs: pattern: 'aws-${{ inputs.identity_scope }}-deployment-files-*' run-id: ${{ inputs.operator_run_number }} path: ./download/artifacts + merge-multiple: true - name: Unzip artifacts if: ${{ inputs.operator_release == '' }} From 024eebb0ab999db80a3f82c04704ab9afb507987 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:35:37 -0600 Subject: [PATCH 0538/1116] remove unzip action --- .github/actions/build_ami/action.yaml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index 3f48874a2..200dc2579 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -78,18 +78,9 @@ runs: repository: IABTechLab/uid2-operator pattern: 'aws-${{ inputs.identity_scope }}-deployment-files-*' run-id: ${{ inputs.operator_run_number }} - path: ./download/artifacts + path: ./scripts/aws/uid2-operator-ami/artifacts merge-multiple: true - - name: Unzip artifacts - if: ${{ inputs.operator_release == '' }} - shell: bash - run: | - ARTIFACTS='${{ steps.get_eif_for_run.outputs.artifacts }}' - FILE=$(echo $ARTIFACTS | jq -r '.[0].name') - unzip -o -d ./scripts/aws/uid2-operator-ami/artifacts $FILE - rm $FILE - - name: Configure UID2 AWS credentials uses: aws-actions/configure-aws-credentials@v4 if: ${{ inputs.identity_scope == 'uid2' }} From a3dcf0842ab84aed9e7b489bff40d3e00159af3d Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 17 Jun 2024 13:38:00 -0600 Subject: [PATCH 0539/1116] reference action on branch for EUID also --- .github/workflows/build-uid2-ami.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-uid2-ami.yaml b/.github/workflows/build-uid2-ami.yaml index 6db8fc68c..1decace4e 100644 --- a/.github/workflows/build-uid2-ami.yaml +++ b/.github/workflows/build-uid2-ami.yaml @@ -79,7 +79,7 @@ jobs: - name: Build EUID Operator AMI id: buildAMI - uses: IABTechLab/uid2-operator/.github/actions/build_ami@main + uses: IABTechLab/uid2-operator/.github/actions/build_ami@ian-UID2-3362-upgrade-java-21 with: identity_scope: euid eif_repo_owner: ${{ env.REPO_OWNER }} From e248c51cf8ed02401f64f2a9edf8450ca595b611 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Mon, 17 Jun 2024 15:30:53 -0700 Subject: [PATCH 0540/1116] Address the comments --- .../operator/vertx/UIDOperatorVerticle.java | 32 ++++++----------- .../operator/UIDOperatorVerticleTest.java | 36 ++++--------------- 2 files changed, 18 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index c948416ca..63acedd12 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -453,7 +453,7 @@ else if(emailHash != null) { input = InputUtil.normalizePhoneHash(phoneHash); } - if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + if (checkTokenInput(input, rc)) { return; } @@ -897,7 +897,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { private void handleTokenValidateV1(RoutingContext rc) { try { final InputUtil.InputVal input = this.phoneSupport ? getTokenInputV1(rc) : getTokenInput(rc); - if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + if (checkTokenInput(input, rc)) { return; } if ((Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Email) @@ -928,7 +928,7 @@ private void handleTokenValidateV2(RoutingContext rc) { final JsonObject req = (JsonObject) rc.data().get("request"); final InputUtil.InputVal input = getTokenInputV2(req); - if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + if (checkTokenInput(input, rc)) { return; } if ((input.getIdentityType() == IdentityType.Email && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput())) @@ -960,7 +960,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { try { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); platformType = getPlatformType(rc); - if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + if (checkTokenInput(input, rc)) { return; } else { final IdentityTokens t = this.idService.generateIdentity( @@ -987,7 +987,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { platformType = getPlatformType(rc); final InputUtil.InputVal input = this.getTokenInputV2(req); - if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + if (checkTokenInput(input, rc)) { return; } else { final String apiContact = getApiContact(rc); @@ -1262,7 +1262,7 @@ private void handleBucketsV2(RoutingContext rc) { private void handleIdentityMapV1(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); - if (this.phoneSupport ? !checkTokenInputV1(input, rc) : !checkTokenInput(input, rc)) { + if (checkTokenInput(input, rc)) { return; } try { @@ -1393,24 +1393,14 @@ private InputUtil.InputVal getTokenInputV1(RoutingContext rc) { private boolean checkTokenInput(InputUtil.InputVal input, RoutingContext rc) { if (input == null) { - ResponseUtil.ClientError(rc, "Required Parameter Missing: exactly one of email or email_hash must be specified"); - return false; - } else if (!input.isValid()) { - ResponseUtil.ClientError(rc, "Invalid Identifier"); - return false; - } - return true; - } - - private boolean checkTokenInputV1(InputUtil.InputVal input, RoutingContext rc) { - if (input == null) { - ResponseUtil.ClientError(rc, "Required Parameter Missing: exactly one of [email, email_hash, phone, phone_hash] must be specified"); - return false; + String message = this.phoneSupport ? "Required Parameter Missing: exactly one of [email, email_hash, phone, phone_hash] must be specified" : "Required Parameter Missing: exactly one of email or email_hash must be specified"; + ResponseUtil.ClientError(rc, message); + return true; } else if (!input.isValid()) { ResponseUtil.ClientError(rc, "Invalid Identifier"); - return false; + return true; } - return true; + return false; } private InputUtil.InputVal[] getIdentityBulkInput(RoutingContext rc) { diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index c990f7768..bc676ffe6 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4162,39 +4162,17 @@ void cstgNoActiveKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAlg }); } - @Test - void cstgInvalidEmailHashInput(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { - setupCstgBackend("cstg.co.uk"); - setupKeys(true); - String email = "random@unifiedid.com"; - - JsonObject identity = new JsonObject(); - identity.put("email_hash", getSha256(email) + getSha256(email)); - identity.put("optout_check", 1); - Tuple.Tuple2 data = createClientSideTokenGenerateRequestWithPayload(identity, Instant.now().toEpochMilli(), null); - - sendCstg(vertx, - "v2/token/client-generate", - "http://cstg.co.uk", - data.getItem1(), - data.getItem2(), - 400, - testContext, - respJson -> { - assertFalse(respJson.containsKey("body")); - assertEquals("Invalid Identifier", respJson.getString("message")); - testContext.completeNow(); - }); - } - - @Test - void cstgInvalidPhoneHashInput(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + @ParameterizedTest + @CsvSource({ + "email_hash,random@unifiedid.com", + "phone_hash,1234567890", + }) + void cstgInvalidInput(String identityType, String rawUID, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk"); setupKeys(true); - String phone = "1234567890"; JsonObject identity = new JsonObject(); - identity.put("phone_hash", getSha256(phone) + getSha256(phone)); + identity.put(identityType, getSha256(rawUID) + getSha256(rawUID)); identity.put("optout_check", 1); Tuple.Tuple2 data = createClientSideTokenGenerateRequestWithPayload(identity, Instant.now().toEpochMilli(), null); From ebe7c59d6056bffb25af832e64ae67fd461f3a32 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 18 Jun 2024 10:32:00 -0600 Subject: [PATCH 0541/1116] use 22.04 during build --- .github/workflows/e2e-azure-cc-enclave.yaml | 117 ------------------- .github/workflows/e2e-gcp-oidc-enclave.yaml | 122 -------------------- Dockerfile.nitro.builder | 2 +- 3 files changed, 1 insertion(+), 240 deletions(-) delete mode 100644 .github/workflows/e2e-azure-cc-enclave.yaml delete mode 100644 .github/workflows/e2e-gcp-oidc-enclave.yaml diff --git a/.github/workflows/e2e-azure-cc-enclave.yaml b/.github/workflows/e2e-azure-cc-enclave.yaml deleted file mode 100644 index f7671ff92..000000000 --- a/.github/workflows/e2e-azure-cc-enclave.yaml +++ /dev/null @@ -1,117 +0,0 @@ -name: E2E AZURE CC Enclave -on: - workflow_dispatch: - inputs: - operator_image_version: - description: 'The version of Azure enclave image' - type: string - required: true - core_image_version: - description: 'The version of UID2 core image' - type: string - default: '2.15.0-50d596678a-default' - optout_image_version: - description: 'The version of UID2 optout image' - type: string - default: '2.6.18-60727cf243-default' - -env: - REGISTRY: ghcr.io - -jobs: - e2e-test: - runs-on: ubuntu-latest - permissions: - contents: write - packages: read - steps: - - name: Checkout full history - uses: actions/checkout@v4 - - - name: Checkout uid2-core repo - uses: actions/checkout@v4 - with: - repository: IABTechLab/uid2-core - token: ${{ secrets.GHCR_PAT }} - path: core - - - name: Checkout uid2-optout repo - uses: actions/checkout@v4 - with: - repository: IABTechLab/uid2-optout - token: ${{ secrets.GHCR_PAT }} - path: optout - - - name: Bring up ngrok - id: ngrok - env: - NGROK_TOKEN: ${{ secrets.NGROK_AUTHTOKEN }} - run: | - cd ./e2e && bash ./setup_ngrok.sh - - - name: Log in to the Docker container registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - # we use personal access token here since we need to pull images from private repo (core) - password: ${{ secrets.GHCR_PAT }} - - - name: Prepare conf files - env: - CORE_ROOT: '../core' - OPTOUT_ROOT: '../optout' - run: | - cd ./e2e && bash ./prepare_conf.sh - - - name: Generate Azure enclave deployment artifacts - id: artifacts - env: - IMAGE_VERSION: ${{ inputs.operator_image_version }} - run: | - cd ./e2e && bash ./prepare_azure_cc_artifacts.sh - - - name: Prepare Azure enclave metadata - id: metadata - env: - OUTPUT_POLICY_DIGEST_FILE: ${{ steps.artifacts.outputs.OUTPUT_POLICY_DIGEST_FILE }} - run: | - cd ./e2e && bash ./prepare_azure_cc_enclave_metadata.sh - - - name: Bring up docker compose - id: docker_compose - env: - NGROK_URL_LOCALSTACK: ${{ steps.ngrok.outputs.NGROK_URL_LOCALSTACK }} - NGROK_URL_CORE: ${{ steps.ngrok.outputs.NGROK_URL_CORE }} - NGROK_URL_OPTOUT: ${{ steps.ngrok.outputs.NGROK_URL_OPTOUT }} - CORE_VERSION: ${{ inputs.core_image_version }} - OPTOUT_VERSION: ${{ inputs.optout_image_version }} - run: | - cd ./e2e && bash ./start_docker.sh - - - name: Azure Login - uses: azure/login@v2 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - - name: Start Azure private operator - id: start_azure - env: - NGROK_URL_CORE: ${{ steps.ngrok.outputs.NGROK_URL_CORE }} - NGROK_URL_OPTOUT: ${{ steps.ngrok.outputs.NGROK_URL_OPTOUT }} - OUTPUT_TEMPLATE_FILE: ${{ steps.artifacts.outputs.OUTPUT_TEMPLATE_FILE }} - OUTPUT_PARAMETERS_FILE: ${{ steps.artifacts.outputs.OUTPUT_PARAMETERS_FILE }} - run: | - cd ./e2e && bash ./start_azure_cc_enclave.sh - - - name: Stop Azure private operator - if: always() - env: - CONTAINER_GROUP_NAME: ${{ steps.start_azure.outputs.CONTAINER_GROUP_NAME }} - run: | - cd ./e2e && bash ./stop_azure_cc_enclave.sh - - - name: Stop ngrok - if: always() - run: | - killall ngrok diff --git a/.github/workflows/e2e-gcp-oidc-enclave.yaml b/.github/workflows/e2e-gcp-oidc-enclave.yaml deleted file mode 100644 index 9c415dcac..000000000 --- a/.github/workflows/e2e-gcp-oidc-enclave.yaml +++ /dev/null @@ -1,122 +0,0 @@ -name: E2E GCP OIDC Enclave -on: - workflow_dispatch: - inputs: - operator_image_hash: - description: 'The hash of GCP enclave image(start with sha256:)' - type: string - required: true - core_image_version: - description: 'The version of UID2 core image' - type: string - default: '2.15.0-50d596678a-default' - optout_image_version: - description: 'The version of UID2 optout image' - type: string - default: '2.6.18-60727cf243-default' - -env: - REGISTRY: ghcr.io - -jobs: - e2e-test: - runs-on: ubuntu-latest - permissions: - contents: write - packages: read - id-token: write - steps: - - name: Checkout full history - uses: actions/checkout@v4 - - - name: Checkout uid2-core repo - uses: actions/checkout@v4 - with: - repository: IABTechLab/uid2-core - token: ${{ secrets.GHCR_PAT }} - path: core - - - name: Checkout uid2-optout repo - uses: actions/checkout@v4 - with: - repository: IABTechLab/uid2-optout - token: ${{ secrets.GHCR_PAT }} - path: optout - - - name: Bring up ngrok - id: ngrok - env: - NGROK_TOKEN: ${{ secrets.NGROK_AUTHTOKEN }} - run: | - cd ./e2e && bash ./setup_ngrok.sh - - - name: Prepare GCP enclave metadata - id: metadata - env: - IMAGE_HASH: ${{ inputs.operator_image_hash }} - run: | - cd ./e2e && bash ./prepare_gcp_enclave_metadata.sh - - - name: Log in to the Docker container registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - # we use personal access token here since we need to pull images from private repo (core) - password: ${{ secrets.GHCR_PAT }} - - - name: Prepare conf files - env: - CORE_ROOT: '../core' - OPTOUT_ROOT: '../optout' - run: | - cd ./e2e && bash ./prepare_conf.sh - - - name: Bring up docker compose - id: docker-compose - env: - NGROK_URL_LOCALSTACK: ${{ steps.ngrok.outputs.NGROK_URL_LOCALSTACK }} - NGROK_URL_CORE: ${{ steps.ngrok.outputs.NGROK_URL_CORE }} - NGROK_URL_OPTOUT: ${{ steps.ngrok.outputs.NGROK_URL_OPTOUT }} - CORE_VERSION: ${{ inputs.core_image_version }} - OPTOUT_VERSION: ${{ inputs.optout_image_version }} - run: | - cd ./e2e && bash ./start_docker.sh - - - name: Authenticate with Google Cloud - id: gcp_auth - uses: google-github-actions/auth@v0 - with: - token_format: access_token - workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER_ID }} - service_account: ${{ vars.GCP_SERVICE_ACCOUNT }} - access_token_lifetime: 1200s - - - name: Set up Cloud SDK - uses: 'google-github-actions/setup-gcloud@v1' - - - name: Start GCP private operator - id: start_gcp - env: - GCP_PROJECT: ${{ vars.GCP_PROJECT }} - SERVICE_ACCOUNT: ${{ vars.GCP_SERVICE_ACCOUNT }} - NGROK_URL_CORE: ${{ steps.ngrok.outputs.NGROK_URL_CORE }} - NGROK_URL_OPTOUT: ${{ steps.ngrok.outputs.NGROK_URL_OPTOUT }} - OPERATOR_KEY: ${{ steps.metadata.outputs.OPERATOR_KEY }} - IMAGE_HASH: ${{ inputs.operator_image_hash }} - run: | - cd ./e2e && bash ./start_gcp_enclave.sh - - - name: Stop GCP private operator - if: always() - env: - GCP_PROJECT: ${{ vars.GCP_PROJECT }} - SERVICE_ACCOUNT: ${{ vars.GCP_SERVICE_ACCOUNT }} - GCP_INSTANCE_NAME: ${{ steps.start_gcp.outputs.GCP_INSTANCE_NAME }} - run: | - cd ./e2e && bash ./stop_gcp_enclave.sh - - - name: Stop ngrok - if: always() - run: | - killall ngrok diff --git a/Dockerfile.nitro.builder b/Dockerfile.nitro.builder index d79c26077..23aaba22b 100644 --- a/Dockerfile.nitro.builder +++ b/Dockerfile.nitro.builder @@ -1,4 +1,4 @@ -FROM ubuntu:24.04 +FROM ubuntu:22.04 ENV enclave_platform="aws-nitro" From 63ad0ffbc0c6fe5272566da2aa27489523287469 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 18 Jun 2024 10:33:24 -0600 Subject: [PATCH 0542/1116] remove comment --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 944b562c2..e349b514d 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -127,11 +127,6 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error -# - name: Show disk usage -# shell: bash -# run: -# du -h / - - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 From de271d4ab7be0bd2bf793263d858615a114f3e6a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 18 Jun 2024 16:35:34 +0000 Subject: [PATCH 0543/1116] [CI Pipeline] Released Snapshot version: 5.37.38-alpha-166-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2c6b94aea..26933e569 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.37-alpha-165-SNAPSHOT + 5.37.38-alpha-166-SNAPSHOT UTF-8 From 9dfcc5da9ac2621ce7a21d88463b4add62c4eab8 Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Tue, 18 Jun 2024 14:28:47 -0700 Subject: [PATCH 0544/1116] Rename checkTokenInput to checkForInvalidTokenInput --- .../operator/vertx/UIDOperatorVerticle.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 63acedd12..372935da7 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -453,7 +453,7 @@ else if(emailHash != null) { input = InputUtil.normalizePhoneHash(phoneHash); } - if (checkTokenInput(input, rc)) { + if (!checkForInvalidTokenInput(input, rc)) { return; } @@ -897,7 +897,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { private void handleTokenValidateV1(RoutingContext rc) { try { final InputUtil.InputVal input = this.phoneSupport ? getTokenInputV1(rc) : getTokenInput(rc); - if (checkTokenInput(input, rc)) { + if (!checkForInvalidTokenInput(input, rc)) { return; } if ((Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Email) @@ -928,7 +928,7 @@ private void handleTokenValidateV2(RoutingContext rc) { final JsonObject req = (JsonObject) rc.data().get("request"); final InputUtil.InputVal input = getTokenInputV2(req); - if (checkTokenInput(input, rc)) { + if (!checkForInvalidTokenInput(input, rc)) { return; } if ((input.getIdentityType() == IdentityType.Email && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput())) @@ -960,7 +960,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { try { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); platformType = getPlatformType(rc); - if (checkTokenInput(input, rc)) { + if (!checkForInvalidTokenInput(input, rc)) { return; } else { final IdentityTokens t = this.idService.generateIdentity( @@ -987,7 +987,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { platformType = getPlatformType(rc); final InputUtil.InputVal input = this.getTokenInputV2(req); - if (checkTokenInput(input, rc)) { + if (!checkForInvalidTokenInput(input, rc)) { return; } else { final String apiContact = getApiContact(rc); @@ -1262,7 +1262,7 @@ private void handleBucketsV2(RoutingContext rc) { private void handleIdentityMapV1(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); - if (checkTokenInput(input, rc)) { + if (!checkForInvalidTokenInput(input, rc)) { return; } try { @@ -1391,16 +1391,16 @@ private InputUtil.InputVal getTokenInputV1(RoutingContext rc) { return null; } - private boolean checkTokenInput(InputUtil.InputVal input, RoutingContext rc) { + private boolean checkForInvalidTokenInput(InputUtil.InputVal input, RoutingContext rc) { if (input == null) { String message = this.phoneSupport ? "Required Parameter Missing: exactly one of [email, email_hash, phone, phone_hash] must be specified" : "Required Parameter Missing: exactly one of email or email_hash must be specified"; ResponseUtil.ClientError(rc, message); - return true; + return false; } else if (!input.isValid()) { ResponseUtil.ClientError(rc, "Invalid Identifier"); - return true; + return false; } - return false; + return true; } private InputUtil.InputVal[] getIdentityBulkInput(RoutingContext rc) { From 0859c767271f5f25c031ca14543893a2cc77b885 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 2 Jul 2024 01:50:26 +0000 Subject: [PATCH 0545/1116] [CI Pipeline] Released Patch version: 5.37.26 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0754e7e4b..5fbcad4de 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.15 + 5.37.26 UTF-8 From 1fdd5bff206bd755e91c9958eb7ef14a31c7ecf6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 2 Jul 2024 02:35:53 +0000 Subject: [PATCH 0546/1116] [CI Pipeline] Released Patch version: 5.37.28 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5fbcad4de..ce32629dd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.26 + 5.37.28 UTF-8 From 7d2c1c607a60b5e3489235d2be21c24957acd452 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 3 Jul 2024 08:11:40 +1000 Subject: [PATCH 0547/1116] UID2-3699 fix GitHub runner oos issue (#672) * Separate UID2 and EUID EIF build steps * Use needs to get outputs * Test changes on kcc-UID2-2996-parallelize-eif-build * Add checkout step to all the jobs * Revert testing * Download EIFs * Add test branch checkout * Add steps to check disk usage * [CI Pipeline] Released Snapshot version: 5.37.29-alpha-201-SNAPSHOT --------- Co-authored-by: Release Workflow --- .../publish-aws-nitro-enclave-docker.yaml | 155 +++++++++++++++--- pom.xml | 2 +- 2 files changed, 137 insertions(+), 20 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index cbd9e559c..374267e90 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -31,8 +31,8 @@ env: ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts jobs: - buildImage: - name: Build Image + start: + name: Start Building AWS Image runs-on: ubuntu-latest steps: - name: Check branch and release type @@ -113,6 +113,47 @@ jobs: message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} + - name: Check disk usage + shell: bash + run: | + df -h + outputs: + new_version: ${{ steps.version.outputs.new_version }} + is_release: ${{ steps.checkRelease.outputs.is_release }} + github_changelog: ${{ steps.github_release.outputs.changelog }} + + buildUID2EIF: + name: Build UID2 EIF + runs-on: ubuntu-latest + needs: start + steps: + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Free up space - delete preinstalled tools + run: | + rm -rf /opt/hostedtoolcache + + - name: Check disk usage + shell: bash + run: | + df -h + - name: Build UID2 AWS EIF id: build_uid2_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main @@ -120,13 +161,57 @@ jobs: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + - name: Check disk usage + shell: bash + run: | + df -h + - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: - name: aws-uid2-deployment-files-${{ steps.version.outputs.new_version }} + name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error - + + - name: Check disk usage + shell: bash + run: | + df -h + outputs: + uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} + + buildEUIDEIF: + name: Build EUID EIF + runs-on: ubuntu-latest + needs: start + steps: + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Free up space - delete preinstalled tools + run: | + rm -rf /opt/hostedtoolcache + + - name: Check disk usage + shell: bash + run: | + df -h + - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main @@ -134,35 +219,67 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + - name: Check disk usage + shell: bash + run: | + df -h + - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: - name: aws-euid-deployment-files-${{ steps.version.outputs.new_version }} + name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error + - name: Check disk usage + shell: bash + run: | + df -h + outputs: + euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} + + cleanup: + name: Cleanup Building AWS Image + runs-on: ubuntu-latest + needs: [start, buildUID2EIF, buildEUIDEIF] + steps: + - name: Check disk usage + shell: bash + run: | + df -h + + - name: Download UID2 artifacts + uses: actions/download-artifact@v4 + with: + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + + - name: Download EUID artifacts + uses: actions/download-artifact@v4 + with: + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - echo ${{ steps.build_uid2_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - echo ${{ steps.build_euid_eif.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt + echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 with: - name: aws-enclave-ids-${{ steps.version.outputs.new_version }} + name: aws-enclave-ids-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests if-no-files-found: error - name: Generate release archive files - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} run: | - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - name: Build changelog id: github_release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} uses: mikepenz/release-changelog-builder-action@v4 with: configurationJson: | @@ -174,15 +291,15 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create release - if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} uses: softprops/action-gh-release@v2 with: - name: ${{ steps.version.outputs.new_version }} - body: ${{ steps.github_release.outputs.changelog }} + name: ${{ needs.start.outputs.new_version }} + body: ${{ needs.start.outputs.github_changelog }} draft: true files: | - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ steps.version.outputs.new_version }}.zip - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ steps.version.outputs.new_version }}.txt - ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ steps.version.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt diff --git a/pom.xml b/pom.xml index ce32629dd..b412673ca 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.28 + 5.37.29-alpha-201-SNAPSHOT UTF-8 From 46ae1ee387ec9ec8ace27e7f3693e3d2df06cc74 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Fri, 5 Jul 2024 10:42:02 +1000 Subject: [PATCH 0548/1116] UID2-3331 Update ami from al2 to al2023 (#641) * Update AL source * Remove unnecessary arguments * Update installing aws-nitro-enclaves-cli * Use dnf instead of yum * Remove the step for installing epel * Define cut down version of syslog-ng * Update inputs for `actions/download-artifact@v4` * Copy syslog-ng-amazon23.repo to artifacts dir * Temporary change ref to use new files * Update syslog-ng-amazon23.repo path * Add steps to ensure /etc/cron.d/ folder exist * Remove disabling rsyslog * Give cron.d 0755 access * Put in scripts for logrotate under cron.daily * Update external ethernet port name * Add `df -h` to monitor disk usage * Disable DOCKER_BUILDKIT for docker build * Make Makefile.nitro run quietly * Comment out uid2 build * Use .github/workflows/publish-aws-nitro-enclave-docker.yaml for build_aws_eif * Remove --quiet mode * Update start.sh * Install libxcrypt-compat * Modify scripts/aws/entrypoint.sh to match AL2023 metadata standard * Use echo $SECURITY_CREDS to get AWS keys * Convert .github/workflows/publish-aws-nitro-enclave-docker.yaml to main --- .github/actions/build_ami/action.yaml | 5 +- .github/actions/build_aws_eif/action.yaml | 2 + .../publish-aws-nitro-enclave-docker.yaml | 1 - scripts/aws/entrypoint.sh | 17 ++--- scripts/aws/logrotate/logrotateDaily | 8 +++ scripts/aws/sockd.conf | 2 +- scripts/aws/start.sh | 7 +- .../syslog-ng/server/syslog-ng-amazon23.repo | 10 +++ .../uid2-operator-ami/ansible/playbook.yml | 67 +++++++++++-------- scripts/aws/uid2-operator-ami/build.pkr.hcl | 2 +- scripts/aws/uid2-operator-ami/source.pkr.hcl | 3 +- 11 files changed, 75 insertions(+), 49 deletions(-) create mode 100644 scripts/aws/logrotate/logrotateDaily create mode 100644 scripts/aws/syslog-ng/server/syslog-ng-amazon23.repo diff --git a/.github/actions/build_ami/action.yaml b/.github/actions/build_ami/action.yaml index 83e16522f..a614a943d 100644 --- a/.github/actions/build_ami/action.yaml +++ b/.github/actions/build_ami/action.yaml @@ -71,16 +71,13 @@ runs: - name: Get EIF for Run ${{ inputs.operator_run_number }} id: get_eif_for_run - uses: actions/download-artifact@v4 + uses: dawidd6/action-download-artifact@v6 if: ${{ inputs.operator_release == '' }} with: - github_token: ${{ inputs.github_token }} - repo: IABTechLab/uid2-operator name: 'aws-${{ inputs.identity_scope }}-deployment-files-.*' name_is_regexp: true run_id: ${{ inputs.operator_run_number }} skip_unpack: true - path: ./download/artifacts - name: Unzip artifacts if: ${{ inputs.operator_release == '' }} diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 55663e497..c84ee2b68 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -68,8 +68,10 @@ runs: cp ./scripts/aws/syslog-ng/syslog-ng-server.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/syslog-ng/server/syslog-ng-pubkey.gpg ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/syslog-ng/server/syslog-ng-4.6.0-1.el7.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server/syslog-ng-amazon23.repo ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/logrotate/operator-logrotate.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/logrotate/logrotate ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/logrotate/logrotateDaily ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/sockd ${ARTIFACTS_OUTPUT_DIR}/ docker cp amazonlinux:/vsockpx ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 374267e90..7d8611d0a 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -302,4 +302,3 @@ jobs: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt - diff --git a/scripts/aws/entrypoint.sh b/scripts/aws/entrypoint.sh index 73f5debae..2b49660cc 100644 --- a/scripts/aws/entrypoint.sh +++ b/scripts/aws/entrypoint.sh @@ -18,7 +18,8 @@ echo "Starting syslog-ng..." # -- load env vars via proxy echo "Loading env vars via proxy..." -USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data) +TOKEN=$(curl -x socks5h://127.0.0.1:3305 --request PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 3600") +USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data --header "X-aws-ec2-metadata-token: $TOKEN") if [ "${IDENTITY_SCOPE}" = "UID2" ]; then UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then @@ -34,17 +35,17 @@ echo "UID2_CONFIG_SECRET_KEY=${UID2_CONFIG_SECRET_KEY}" echo "CORE_BASE_URL=${CORE_BASE_URL}" echo "OPTOUT_BASE_URL=${OPTOUT_BASE_URL}" -export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r ".region") +export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ --header "X-aws-ec2-metadata-token: $TOKEN" | jq -r ".region") echo "AWS_REGION_NAME=${AWS_REGION_NAME}" echo "127.0.0.1 secretsmanager.${AWS_REGION_NAME}.amazonaws.com" >> /etc/hosts -IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/iam/security-credentials/) +IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/iam/security-credentials/ --header "X-aws-ec2-metadata-token: $TOKEN") echo "IAM_ROLE=${IAM_ROLE}" -CREDS_ENDPOINT="http://169.254.169.254/latest/meta-data/iam/security-credentials/${IAM_ROLE}" -export AWS_ACCESS_KEY_ID=$(curl -s -x socks5h://127.0.0.1:3305 "${CREDS_ENDPOINT}" | jq -r ".AccessKeyId") -export AWS_SECRET_KEY=$(curl -s -x socks5h://127.0.0.1:3305 "${CREDS_ENDPOINT}" | jq -r ".SecretAccessKey") -export AWS_SESSION_TOKEN=$(curl -s -x socks5h://127.0.0.1:3305 "${CREDS_ENDPOINT}" | jq -r ".Token") +SECURITY_CREDS=$(curl -s -x socks5h://127.0.0.1:3305 "http://169.254.169.254/latest/meta-data/iam/security-credentials/${IAM_ROLE}" --header "X-aws-ec2-metadata-token: $TOKEN") +export AWS_ACCESS_KEY_ID=$(echo $SECURITY_CREDS | jq -r ".AccessKeyId") +export AWS_SECRET_KEY=$(echo $SECURITY_CREDS | jq -r ".SecretAccessKey") +export AWS_SESSION_TOKEN=$(echo $SECURITY_CREDS | jq -r ".Token") # -- load configs via proxy echo "Loading config overrides..." @@ -95,7 +96,7 @@ fi cat "${FINAL_CONFIG}" -HOSTNAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/local-hostname) +HOSTNAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/local-hostname --header "X-aws-ec2-metadata-token: $TOKEN") echo "HOSTNAME=${HOSTNAME}" # -- set pwd to /app so we can find default configs diff --git a/scripts/aws/logrotate/logrotateDaily b/scripts/aws/logrotate/logrotateDaily new file mode 100644 index 000000000..967932eec --- /dev/null +++ b/scripts/aws/logrotate/logrotateDaily @@ -0,0 +1,8 @@ +#!/bin/sh + +/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf +EXITVALUE=$? +if [ $EXITVALUE != 0 ]; then + /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" +fi +exit 0 diff --git a/scripts/aws/sockd.conf b/scripts/aws/sockd.conf index 69c6264f8..6e8814445 100644 --- a/scripts/aws/sockd.conf +++ b/scripts/aws/sockd.conf @@ -1,5 +1,5 @@ internal: 127.0.0.1 port = 3306 -external: eth0 +external: ens5 user.notprivileged: ec2-user clientmethod: none socksmethod: none diff --git a/scripts/aws/start.sh b/scripts/aws/start.sh index 705acb80b..a9a08a7ef 100644 --- a/scripts/aws/start.sh +++ b/scripts/aws/start.sh @@ -4,11 +4,12 @@ echo "$HOSTNAME" > /etc/uid2operator/HOSTNAME EIF_PATH=${EIF_PATH:-/opt/uid2operator/uid2operator.eif} IDENTITY_SCOPE=${IDENTITY_SCOPE:-$(cat /opt/uid2operator/identity_scope.txt)} CID=${CID:-42} -AWS_REGION_NAME=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document/ | jq -r '.region') +TOKEN=$(curl --request PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 3600") +AWS_REGION_NAME=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document/ --header "X-aws-ec2-metadata-token: $TOKEN" | jq -r '.region') if [ "$IDENTITY_SCOPE" = 'UID2' ]; then - UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s http://169.254.169.254/latest/user-data | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo ${BASH_REMATCH[1]} || echo "uid2-operator-config-key") + UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s http://169.254.169.254/latest/user-data/ --header "X-aws-ec2-metadata-token: $TOKEN" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo ${BASH_REMATCH[1]} || echo "uid2-operator-config-key") elif [ "$IDENTITY_SCOPE" = 'EUID' ]; then - UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s http://169.254.169.254/latest/user-data | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo ${BASH_REMATCH[1]} || echo "euid-operator-config-key") + UID2_CONFIG_SECRET_KEY=$([[ "$(curl -s http://169.254.169.254/latest/user-data/ --header "X-aws-ec2-metadata-token: $TOKEN" | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\" ]] && echo ${BASH_REMATCH[1]} || echo "euid-operator-config-key") else echo "Unrecognized IDENTITY_SCOPE $IDENTITY_SCOPE" exit 1 diff --git a/scripts/aws/syslog-ng/server/syslog-ng-amazon23.repo b/scripts/aws/syslog-ng/server/syslog-ng-amazon23.repo new file mode 100644 index 000000000..7f93985a1 --- /dev/null +++ b/scripts/aws/syslog-ng/server/syslog-ng-amazon23.repo @@ -0,0 +1,10 @@ +[copr:copr.fedorainfracloud.org:czanik:syslog-ng-amazon23] +name=Copr repo for syslog-ng-amazon23 owned by czanik +baseurl=https://download.copr.fedorainfracloud.org/results/czanik/syslog-ng-amazon23/amazonlinux-2023-$basearch/ +type=rpm-md +skip_if_unavailable=True +gpgcheck=1 +gpgkey=https://download.copr.fedorainfracloud.org/results/czanik/syslog-ng-amazon23/pubkey.gpg +repo_gpgcheck=0 +enabled=1 +enabled_metadata=1 diff --git a/scripts/aws/uid2-operator-ami/ansible/playbook.yml b/scripts/aws/uid2-operator-ami/ansible/playbook.yml index f80f5f013..36e3d4a8f 100644 --- a/scripts/aws/uid2-operator-ami/ansible/playbook.yml +++ b/scripts/aws/uid2-operator-ami/ansible/playbook.yml @@ -9,13 +9,13 @@ tasks: - name: Update all base packages - ansible.builtin.yum: + ansible.builtin.dnf: update_cache: yes name: '*' state: latest - name: Install Netcat - ansible.builtin.yum: + ansible.builtin.dnf: name: nmap-ncat state: latest @@ -29,6 +29,11 @@ path: /opt/uid2operator state: directory + - name: Install libxcrypt-compat + ansible.builtin.dnf: + name: libxcrypt-compat + state: latest + - name: vsock-proxy config ansible.builtin.copy: src: /tmp/artifacts/proxies.host.yaml @@ -115,10 +120,17 @@ dest: /etc/systemd/system/uid2operator.service remote_src: yes - - name: Ensure nitro-cli is installed to the latest version - ansible.builtin.command: amazon-linux-extras install aws-nitro-enclaves-cli + - name: Install AWS Nitro Enclaves CLI + ansible.builtin.dnf: + name: aws-nitro-enclaves-cli + state: latest + + - name: Install AWS Nitro Enclaves Devel CLI + ansible.builtin.dnf: + name: aws-nitro-enclaves-cli-devel + state: latest - - name: Ensure nitro enclave allocator is enabled at boot + - name: Enable the Nitro Enclave allocator service at boot ansible.builtin.systemd: name: nitro-enclaves-allocator.service enabled: yes @@ -133,27 +145,17 @@ # ansible.builtin.systemd: # name: nitro-enclaves-allocator.service # state: restarted - - name: Install EPEL - ansible.builtin.command: amazon-linux-extras install epel - - name: Install ivykis - ansible.builtin.yum: - name: ivykis-0.36.2-2.el7 - state: present - - - name: Install libnet - ansible.builtin.yum: - name: libnet-1.1.6-7.amzn2.0.2 - state: present - - - name: Register Public key - ansible.builtin.command: rpmkeys --import /opt/uid2operator/syslog-ng-pubkey.gpg - - - name: Install package - ansible.builtin.command: rpm -U /opt/uid2operator/syslog-ng-4.6.0-1.el7.x86_64.rpm + - name: Define cutdown version of syslog-ng + ansible.builtin.copy: + src: /tmp/artifacts/syslog-ng-amazon23.repo + dest: /etc/yum.repos.d/ + remote_src: yes - - name: unregister Public key - ansible.builtin.command: rpm -e gpg-pubkey-c57846f4-65a8cf14 + - name: Install syslog-ng + ansible.builtin.dnf: + name: syslog-ng + state: latest - name: syslog-ng config ansible.builtin.copy: @@ -166,6 +168,12 @@ src: /tmp/artifacts/operator-logrotate.conf dest: /etc/logrotate.d/operator-logrotate.conf remote_src: yes + + - name: Ensure /etc/cron.d/ folder exist + ansible.builtin.file: + path: /etc/cron.d + state: directory + mode: 0755 - name: Run logrotate under cron.d ansible.builtin.copy: @@ -174,11 +182,12 @@ mode: 0644 remote_src: yes - - name: Ensure rsyslog is disabled at boot - ansible.builtin.systemd: - name: rsyslog - state: stopped - enabled: false + - name: Run logrotate under cron.daily + ansible.builtin.copy: + src: /tmp/artifacts/logrotateDaily + dest: /etc/cron.daily/logrotate + mode: 0700 + remote_src: yes - name: Ensure syslog-ng is enabled at boot ansible.builtin.systemd: diff --git a/scripts/aws/uid2-operator-ami/build.pkr.hcl b/scripts/aws/uid2-operator-ami/build.pkr.hcl index 36d43390e..72addf7c6 100644 --- a/scripts/aws/uid2-operator-ami/build.pkr.hcl +++ b/scripts/aws/uid2-operator-ami/build.pkr.hcl @@ -8,7 +8,7 @@ build { provisioner "ansible" { playbook_file = "./ansible/playbook.yml" - extra_arguments = [ "--scp-extra-args", "'-O'", "--version", "9.6.1" ] + extra_arguments = [ "--scp-extra-args", "'-O'" ] } post-processor "manifest" { diff --git a/scripts/aws/uid2-operator-ami/source.pkr.hcl b/scripts/aws/uid2-operator-ami/source.pkr.hcl index b12766b0e..2c36b9086 100644 --- a/scripts/aws/uid2-operator-ami/source.pkr.hcl +++ b/scripts/aws/uid2-operator-ami/source.pkr.hcl @@ -3,9 +3,8 @@ source "amazon-ebs" "linux" { # source parameters source_ami_filter { filters = { - name = "amzn2-ami-hvm-*-x86_64-ebs" + name = "al2023-ami-2023*-x86_64" root-device-type = "ebs" - virtualization-type = "hvm" } most_recent = true owners = ["amazon"] From 8506e5625c93bee961e8c3e9face62e00a8a5b48 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 15:23:34 +0000 Subject: [PATCH 0549/1116] [CI Pipeline] Released Snapshot version: 5.37.39-alpha-207-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 26933e569..ad943a66f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.38-alpha-166-SNAPSHOT + 5.37.39-alpha-207-SNAPSHOT UTF-8 From cd8847e78911fda2b4c253c3e357384c12298075 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 15:41:04 +0000 Subject: [PATCH 0550/1116] [CI Pipeline] Released Snapshot version: 5.37.40-alpha-208-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ad943a66f..1e60c2a84 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.39-alpha-207-SNAPSHOT + 5.37.40-alpha-208-SNAPSHOT UTF-8 From 0e8e5950c4bef69bbb7cc15aaf2205ce4bf7e318 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 15:48:51 +0000 Subject: [PATCH 0551/1116] [CI Pipeline] Released Snapshot version: 5.37.16-alpha-209-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f1002b4e3..4d2fa6eb8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.15 + 5.37.16-alpha-209-SNAPSHOT UTF-8 From 0b530603f71c66c666e07f35ffbc1b9b388c25d6 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 09:50:23 -0600 Subject: [PATCH 0552/1116] removing invalidated changes --- .github/actions/build_aws_eif/action.yaml | 4 ++-- .github/workflows/build-uid2-ami.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index fd48ee91a..c84ee2b68 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -84,5 +84,5 @@ runs: - name: Cleanup shell: bash run: | - docker rm -vf $(docker ps -aq) - docker rmi -f $(docker images -aq) + docker stop $(docker ps -a -q) + docker system prune -f diff --git a/.github/workflows/build-uid2-ami.yaml b/.github/workflows/build-uid2-ami.yaml index 1decace4e..7a202a5c8 100644 --- a/.github/workflows/build-uid2-ami.yaml +++ b/.github/workflows/build-uid2-ami.yaml @@ -41,7 +41,7 @@ jobs: - name: Build UID2 Operator AMI id: buildAMI - uses: IABTechLab/uid2-operator/.github/actions/build_ami@ian-UID2-3362-upgrade-java-21 + uses: IABTechLab/uid2-operator/.github/actions/build_ami@main with: identity_scope: uid2 eif_repo_owner: ${{ env.REPO_OWNER }} @@ -79,7 +79,7 @@ jobs: - name: Build EUID Operator AMI id: buildAMI - uses: IABTechLab/uid2-operator/.github/actions/build_ami@ian-UID2-3362-upgrade-java-21 + uses: IABTechLab/uid2-operator/.github/actions/build_ami@main with: identity_scope: euid eif_repo_owner: ${{ env.REPO_OWNER }} From 15b26b4ec0a5505826a88768d9ec9f464e8a3aa3 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 09:53:29 -0600 Subject: [PATCH 0553/1116] removing invalidated changes --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 82c9a535f..5eff61256 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -156,7 +156,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -214,7 +214,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 030310f711ed0b141d955302718769368ddea7f6 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 15:59:03 +0000 Subject: [PATCH 0554/1116] [CI Pipeline] Released Snapshot version: 5.37.17-alpha-210-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4d2fa6eb8..70f566059 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.16-alpha-209-SNAPSHOT + 5.37.17-alpha-210-SNAPSHOT UTF-8 From 38e1c6efb519f3d6c27c6d2bb482047e471b4f21 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 10:20:11 -0600 Subject: [PATCH 0555/1116] serialize jobs and strengthen clean up to handle out of disk space --- .github/actions/build_aws_eif/action.yaml | 4 ++-- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index c84ee2b68..fd48ee91a 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -84,5 +84,5 @@ runs: - name: Cleanup shell: bash run: | - docker stop $(docker ps -a -q) - docker system prune -f + docker rm -vf $(docker ps -aq) + docker rmi -f $(docker images -aq) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 5eff61256..e0defe8f9 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -156,7 +156,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -183,7 +183,7 @@ jobs: buildEUIDEIF: name: Build EUID EIF runs-on: ubuntu-latest - needs: start + needs: buildUID2EIF steps: - name: Checkout full history on Main uses: actions/checkout@v4 @@ -214,7 +214,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 5a7c095595232ed9bba5bd8f502df1d8ecf93bbe Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 16:21:12 +0000 Subject: [PATCH 0556/1116] [CI Pipeline] Released Snapshot version: 5.37.18-alpha-211-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 70f566059..c0bd37030 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.17-alpha-210-SNAPSHOT + 5.37.18-alpha-211-SNAPSHOT UTF-8 From 1bb594de8e8082263d6a8f458e2d87996667d1e0 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 10:34:05 -0600 Subject: [PATCH 0557/1116] remove disk space check --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index e0defe8f9..3461ff77a 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -173,10 +173,6 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error - - name: Check disk usage - shell: bash - run: | - df -h outputs: uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} @@ -207,11 +203,6 @@ jobs: run: | rm -rf /opt/hostedtoolcache - - name: Check disk usage - shell: bash - run: | - df -h - - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 From d5e160d818270ecd9e38441bb089cbe345159889 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 16:36:00 +0000 Subject: [PATCH 0558/1116] [CI Pipeline] Released Snapshot version: 5.37.19-alpha-212-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c0bd37030..5cc2f34b5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.18-alpha-211-SNAPSHOT + 5.37.19-alpha-212-SNAPSHOT UTF-8 From 37b7a978f5a6a92f0a4f49f1e2cff6360767db42 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 10:46:59 -0600 Subject: [PATCH 0559/1116] remove disk space check --- .../publish-aws-nitro-enclave-docker.yaml | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 3461ff77a..1f1e040fc 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -113,10 +113,6 @@ jobs: message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} - - name: Check disk usage - shell: bash - run: | - df -h outputs: new_version: ${{ steps.version.outputs.new_version }} is_release: ${{ steps.checkRelease.outputs.is_release }} @@ -149,11 +145,6 @@ jobs: run: | rm -rf /opt/hostedtoolcache - - name: Check disk usage - shell: bash - run: | - df -h - - name: Build UID2 AWS EIF id: build_uid2_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 @@ -161,11 +152,6 @@ jobs: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - - name: Check disk usage - shell: bash - run: | - df -h - - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: @@ -179,7 +165,7 @@ jobs: buildEUIDEIF: name: Build EUID EIF runs-on: ubuntu-latest - needs: buildUID2EIF + needs: start steps: - name: Checkout full history on Main uses: actions/checkout@v4 @@ -210,11 +196,6 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - - name: Check disk usage - shell: bash - run: | - df -h - - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: @@ -222,10 +203,6 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error - - name: Check disk usage - shell: bash - run: | - df -h outputs: euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} @@ -234,11 +211,6 @@ jobs: runs-on: ubuntu-latest needs: [start, buildUID2EIF, buildEUIDEIF] steps: - - name: Check disk usage - shell: bash - run: | - df -h - - name: Download UID2 artifacts uses: actions/download-artifact@v4 with: From cb5a1eac975b8ee9963d4d5e33be023f9544bd22 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 16:47:53 +0000 Subject: [PATCH 0560/1116] [CI Pipeline] Released Snapshot version: 5.37.20-alpha-213-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5cc2f34b5..d8296d34a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.19-alpha-212-SNAPSHOT + 5.37.20-alpha-213-SNAPSHOT UTF-8 From 9fd367e6d46d64df24f63071f82146e6ffe3b5d0 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 19:18:12 +0000 Subject: [PATCH 0561/1116] [CI Pipeline] Released Snapshot version: 5.37.21-alpha-214-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8296d34a..96cdce98a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.20-alpha-213-SNAPSHOT + 5.37.21-alpha-214-SNAPSHOT UTF-8 From e7fb0cf4345ca25ebb8edcc01ec4048ecab0a435 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 13:32:27 -0600 Subject: [PATCH 0562/1116] try cleanup immediately after eif build --- .github/actions/build_aws_eif/action.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index fd48ee91a..b1a0335c0 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -49,6 +49,12 @@ runs: run: | make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif + - name: Cleanup + shell: bash + run: | + docker rm -vf $(docker ps -aq) + docker rmi -f $(docker images -aq) + - name: Prepare artifacts id: prepare_artifacts shell: bash @@ -80,9 +86,3 @@ runs: docker cp amazonlinux:/pcr0.txt ${{ steps.buildFolder.outputs.BUILD_FOLDER }} docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ echo "enclave_id=$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER}}/pcr0.txt)" >> $GITHUB_OUTPUT - - - name: Cleanup - shell: bash - run: | - docker rm -vf $(docker ps -aq) - docker rmi -f $(docker images -aq) From 926804195a3acbfbfdf40db58fb95c4ee231fca2 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 19:33:31 +0000 Subject: [PATCH 0563/1116] [CI Pipeline] Released Snapshot version: 5.37.22-alpha-215-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96cdce98a..11c8c2db5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.21-alpha-214-SNAPSHOT + 5.37.22-alpha-215-SNAPSHOT UTF-8 From 5d362954447a3b6b721a5ea01e7dcda590ad8b3c Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 14:02:13 -0600 Subject: [PATCH 0564/1116] try to keep amazonlinux container running --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index b1a0335c0..fe28de4de 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Cleanup shell: bash run: | - docker rm -vf $(docker ps -aq) + docker rm -vf $(docker ps -a | grep -v "amazonlinux" | awk 'NR>1 {print $1}') docker rmi -f $(docker images -aq) - name: Prepare artifacts From 715dadcf8877ea9b64483b297b054362bc23590b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 20:03:29 +0000 Subject: [PATCH 0565/1116] [CI Pipeline] Released Snapshot version: 5.37.23-alpha-216-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 11c8c2db5..65b6d3ca1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.22-alpha-215-SNAPSHOT + 5.37.23-alpha-216-SNAPSHOT UTF-8 From eb43150adb1639f71d4167a2131c10863c946568 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 14:56:28 -0600 Subject: [PATCH 0566/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index fe28de4de..c22e62df5 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -49,11 +49,10 @@ runs: run: | make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif - - name: Cleanup + - name: Free up space shell: bash run: | - docker rm -vf $(docker ps -a | grep -v "amazonlinux" | awk 'NR>1 {print $1}') - docker rmi -f $(docker images -aq) + docker image prune -a - name: Prepare artifacts id: prepare_artifacts @@ -86,3 +85,9 @@ runs: docker cp amazonlinux:/pcr0.txt ${{ steps.buildFolder.outputs.BUILD_FOLDER }} docker cp amazonlinux:/pcr0.txt ${ARTIFACTS_OUTPUT_DIR}/ echo "enclave_id=$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER}}/pcr0.txt)" >> $GITHUB_OUTPUT + + - name: Cleanup + shell: bash + run: | + docker rm -vf $(docker ps -a | grep -v "amazonlinux" | awk 'NR>1 {print $1}') + docker rmi -f $(docker images -aq) \ No newline at end of file From 4e61d0fa25352c02f6684407a2f96d1ee0410d44 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 20:57:44 +0000 Subject: [PATCH 0567/1116] [CI Pipeline] Released Snapshot version: 5.37.24-alpha-217-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 65b6d3ca1..4bac5a299 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.23-alpha-216-SNAPSHOT + 5.37.24-alpha-217-SNAPSHOT UTF-8 From f4686b2b092d7634edf611473f240ae8ab948561 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 15:39:30 -0600 Subject: [PATCH 0568/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index c22e62df5..00c3ad4be 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Free up space shell: bash run: | - docker image prune -a + docker system prune -a - name: Prepare artifacts id: prepare_artifacts From 5e9b92e4b19bab6f95434c85fb5c7ea88f6023e7 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 21:40:34 +0000 Subject: [PATCH 0569/1116] [CI Pipeline] Released Snapshot version: 5.37.25-alpha-218-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4bac5a299..59b4da834 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.24-alpha-217-SNAPSHOT + 5.37.25-alpha-218-SNAPSHOT UTF-8 From 888bfab7de4549a391d098d62c88e71af35cc03c Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 15:51:20 -0600 Subject: [PATCH 0570/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 00c3ad4be..92e280b2f 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Free up space shell: bash run: | - docker system prune -a + yes | docker system prune -a - name: Prepare artifacts id: prepare_artifacts From 155241a033122f611e7e913cd2452d1cda60aeea Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 21:52:10 +0000 Subject: [PATCH 0571/1116] [CI Pipeline] Released Snapshot version: 5.37.26-alpha-219-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 59b4da834..46ac1a4c4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.25-alpha-218-SNAPSHOT + 5.37.26-alpha-219-SNAPSHOT UTF-8 From 7ac40c678e109d816dbd037ea8796545057eb650 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 16:16:09 -0600 Subject: [PATCH 0572/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 92e280b2f..a76851db7 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Free up space shell: bash run: | - yes | docker system prune -a + echo yes | docker system prune -a - name: Prepare artifacts id: prepare_artifacts From 7c75b456f9dc37b1c117f022be49b394656cbd0f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 22:36:23 +0000 Subject: [PATCH 0573/1116] [CI Pipeline] Released Snapshot version: 5.37.27-alpha-220-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 46ac1a4c4..04915405e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.26-alpha-219-SNAPSHOT + 5.37.27-alpha-220-SNAPSHOT UTF-8 From d4321e0fc81b189f473043e1d3ad82b55aa24735 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 8 Jul 2024 22:46:51 +0000 Subject: [PATCH 0574/1116] [CI Pipeline] Released Snapshot version: 5.37.28-alpha-221-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 04915405e..2547b555b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.27-alpha-220-SNAPSHOT + 5.37.28-alpha-221-SNAPSHOT UTF-8 From d161e578530dd95d197cbbc4b590916e328e4889 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 18:22:03 -0600 Subject: [PATCH 0575/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index a76851db7..cf75ffd64 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Free up space shell: bash run: | - echo yes | docker system prune -a + echo y | docker system prune -a - name: Prepare artifacts id: prepare_artifacts From feb1be486bd7a0845e5e22540eacd52495b9b8a1 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 00:22:57 +0000 Subject: [PATCH 0576/1116] [CI Pipeline] Released Snapshot version: 5.37.29-alpha-222-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2547b555b..4ac8bb7c4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.28-alpha-221-SNAPSHOT + 5.37.29-alpha-222-SNAPSHOT UTF-8 From ee27a570cd08eb7c1f7293609d9215a1243d3131 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Mon, 8 Jul 2024 18:24:35 -0600 Subject: [PATCH 0577/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index cf75ffd64..3b73c8feb 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Free up space shell: bash run: | - echo y | docker system prune -a + echo -y | docker system prune -a - name: Prepare artifacts id: prepare_artifacts From ea1541c8f1ebba247360824e5ac0afae898afa26 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 00:25:47 +0000 Subject: [PATCH 0578/1116] [CI Pipeline] Released Snapshot version: 5.37.30-alpha-223-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ac8bb7c4..1d6d94158 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.29-alpha-222-SNAPSHOT + 5.37.30-alpha-223-SNAPSHOT UTF-8 From 9003adcc5e8cf0c8a6dda5a31ce07d27773ad2a3 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 9 Jul 2024 12:27:46 -0600 Subject: [PATCH 0579/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index 3b73c8feb..cf75ffd64 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -52,7 +52,7 @@ runs: - name: Free up space shell: bash run: | - echo -y | docker system prune -a + echo y | docker system prune -a - name: Prepare artifacts id: prepare_artifacts From 6b57cfe71dcdcbbf55793e6e31823f3a57316b70 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 18:30:41 +0000 Subject: [PATCH 0580/1116] [CI Pipeline] Released Snapshot version: 5.37.31-alpha-224-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1d6d94158..e59257bf0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.30-alpha-223-SNAPSHOT + 5.37.31-alpha-224-SNAPSHOT UTF-8 From 3aea4ba0983509a500a762cd592f326a989639b2 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 9 Jul 2024 13:13:51 -0600 Subject: [PATCH 0581/1116] try docker prune --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index cf75ffd64..cb9256567 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -89,5 +89,5 @@ runs: - name: Cleanup shell: bash run: | - docker rm -vf $(docker ps -a | grep -v "amazonlinux" | awk 'NR>1 {print $1}') + docker rm -vf $(docker ps -a -q) docker rmi -f $(docker images -aq) \ No newline at end of file From 80c191faa1dbae88c5849c7259911c016ae9bdde Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 19:14:51 +0000 Subject: [PATCH 0582/1116] [CI Pipeline] Released Snapshot version: 5.37.32-alpha-225-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e59257bf0..62a66b032 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.31-alpha-224-SNAPSHOT + 5.37.32-alpha-225-SNAPSHOT UTF-8 From 7521509fbb53226fe3a398f1619c2be006ccc874 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 20:39:16 +0000 Subject: [PATCH 0583/1116] [CI Pipeline] Released Snapshot version: 5.37.33-alpha-111-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 62a66b032..0e057ba45 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.32-alpha-225-SNAPSHOT + 5.37.33-alpha-111-SNAPSHOT UTF-8 From 15ef7148609d9d51b5ff48184855c80a21f8dbf1 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 20:43:16 +0000 Subject: [PATCH 0584/1116] [CI Pipeline] Released Snapshot version: 5.37.34-alpha-141-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0e057ba45..86038b993 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.33-alpha-111-SNAPSHOT + 5.37.34-alpha-141-SNAPSHOT UTF-8 From d669f8ac1aa17a43b0aa0df0bd58625aa56b3bc8 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 20:48:23 +0000 Subject: [PATCH 0585/1116] [CI Pipeline] Released Snapshot version: 5.37.35-alpha-86-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 86038b993..4c6f1ff60 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.34-alpha-141-SNAPSHOT + 5.37.35-alpha-86-SNAPSHOT UTF-8 From b4b55181b1468bb33d70b90364a9e30a91528b10 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 9 Jul 2024 15:34:25 -0600 Subject: [PATCH 0586/1116] check disk usage --- .../publish-aws-nitro-enclave-docker.yaml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 1f1e040fc..9a47377ab 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -113,6 +113,11 @@ jobs: message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' tag: v${{ steps.version.outputs.new_version }} + - name: Check disk usage + shell: bash + run: | + df -h + outputs: new_version: ${{ steps.version.outputs.new_version }} is_release: ${{ steps.checkRelease.outputs.is_release }} @@ -152,6 +157,11 @@ jobs: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + - name: Check disk usage + shell: bash + run: | + df -h + - name: Save UID2 eif artifact uses: actions/upload-artifact@v4 with: @@ -159,6 +169,11 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 if-no-files-found: error + - name: Check disk usage + shell: bash + run: | + df -h + outputs: uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} @@ -189,6 +204,11 @@ jobs: run: | rm -rf /opt/hostedtoolcache + - name: Check disk usage + shell: bash + run: | + df -h + - name: Build EUID AWS EIF id: build_euid_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 @@ -196,6 +216,11 @@ jobs: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + - name: Check disk usage + shell: bash + run: | + df -h + - name: Save EUID eif artifact uses: actions/upload-artifact@v4 with: @@ -203,6 +228,11 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid if-no-files-found: error + - name: Check disk usage + shell: bash + run: | + df -h + outputs: euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} @@ -211,6 +241,11 @@ jobs: runs-on: ubuntu-latest needs: [start, buildUID2EIF, buildEUIDEIF] steps: + - name: Check disk usage + shell: bash + run: | + df -h + - name: Download UID2 artifacts uses: actions/download-artifact@v4 with: From 49ca916f850f341800c3d2ebdc765f1b6936a582 Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 9 Jul 2024 15:35:46 -0600 Subject: [PATCH 0587/1116] check disk usage --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 9a47377ab..3942fedfd 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -150,6 +150,11 @@ jobs: run: | rm -rf /opt/hostedtoolcache + - name: Check disk usage + shell: bash + run: | + df -h + - name: Build UID2 AWS EIF id: build_uid2_eif uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 From f7aa3d2fc493c5aa3fd656cb86698b20fae0e18a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 9 Jul 2024 21:36:37 +0000 Subject: [PATCH 0588/1116] [CI Pipeline] Released Snapshot version: 5.37.36-alpha-226-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4c6f1ff60..21baaa28e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.35-alpha-86-SNAPSHOT + 5.37.36-alpha-226-SNAPSHOT UTF-8 From ee3a6537e7da7cbc54112c1a043246566fb88c8d Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Wed, 10 Jul 2024 15:10:46 -0600 Subject: [PATCH 0589/1116] fix typo, improve tests --- src/main/java/com/uid2/operator/service/ShutdownService.java | 2 +- .../java/com/uid2/operator/OperatorShutdownHandlerTest.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/ShutdownService.java b/src/main/java/com/uid2/operator/service/ShutdownService.java index e4cd3f57f..fe3fa9d03 100644 --- a/src/main/java/com/uid2/operator/service/ShutdownService.java +++ b/src/main/java/com/uid2/operator/service/ShutdownService.java @@ -4,7 +4,7 @@ public class ShutdownService { public void Shutdown(int status) { System.exit(status); - // according to the docks, this should not be reached as System.exit does not complete either normally or abruptly. + // according to the docs, this should not be reached as System.exit does not complete either normally or abruptly. // Added for safety throw new RuntimeException("JVM Requested to shut down"); } diff --git a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java index a811b2fdc..e4323226c 100644 --- a/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java +++ b/src/test/java/com/uid2/operator/OperatorShutdownHandlerTest.java @@ -98,6 +98,7 @@ void attestRecoverOnSuccess(VertxTestContext testContext) { assertDoesNotThrow(() -> { this.operatorShutdownHandler.handleAttestResponse(Pair.of(500, "")); }); + verify(shutdownService, never()).Shutdown(anyInt()); testContext.completeNow(); } @@ -114,8 +115,8 @@ void shutdownOnSaltsExpiredTooLong(VertxTestContext testContext) { Assertions.assertThrows(RuntimeException.class, () -> { this.operatorShutdownHandler.handleSaltRetrievalResponse(true); }); - verify(shutdownService).Shutdown(1); Assertions.assertAll("Expired Salts Log Messages", + () -> verify(shutdownService).Shutdown(1), () -> Assertions.assertTrue(logWatcher.list.get(1).getFormattedMessage().contains("all salts are expired")), () -> Assertions.assertTrue(logWatcher.list.get(2).getFormattedMessage().contains("salts have been in expired state for too long. shutting down operator")), () -> Assertions.assertEquals(3, logWatcher.list.size())); @@ -140,6 +141,7 @@ void saltsRecoverOnSuccess(VertxTestContext testContext) { this.operatorShutdownHandler.handleSaltRetrievalResponse(false); }); Assertions.assertEquals(2, logWatcher.list.size()); + verify(shutdownService, never()).Shutdown(anyInt()); testContext.completeNow(); } From 74385b56c2673e310df56007817ce366e1ac487a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Jul 2024 12:29:14 -0600 Subject: [PATCH 0590/1116] change action back to referencing main --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 3942fedfd..8a5ca215b 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -157,7 +157,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -216,7 +216,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@ian-UID2-3362-upgrade-java-21 + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 01678eb4cab25f1bc879dddb7db715691f44c468 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 11 Jul 2024 19:00:21 +0000 Subject: [PATCH 0591/1116] [CI Pipeline] Released Patch version: 5.37.119 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 21baaa28e..88c5d6e3b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.36-alpha-226-SNAPSHOT + 5.37.119 UTF-8 From 6dfc66c816f463bf8eedf257cc3115adb79c937a Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Thu, 11 Jul 2024 15:42:00 -0600 Subject: [PATCH 0592/1116] return 400 on invalid base64 refresh token --- .../com/uid2/operator/service/EncryptedTokenEncoder.java | 7 ++++++- .../java/com/uid2/operator/UIDOperatorVerticleTest.java | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 9be14663b..4c0a99b1e 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -75,7 +75,12 @@ private byte[] encodeV3(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteK @Override public RefreshToken decodeRefreshToken(String s) { if (s != null && !s.isEmpty()) { - final byte[] bytes = EncodingUtils.fromBase64(s); + final byte[] bytes; + try { + bytes = EncodingUtils.fromBase64(s); + } catch (IllegalArgumentException e) { + throw new ClientInputValidationException("Invalid refresh token"); + } final Buffer b = Buffer.buffer(bytes); if (b.getByte(1) == TokenVersion.V3.rawVersion) { return decodeRefreshTokenV3(b, bytes); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index bc676ffe6..8e49aabb1 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1645,12 +1645,12 @@ void tokenRefreshNoToken(String apiVersion, Vertx vertx, VertxTestContext testCo } @ParameterizedTest - @ValueSource(strings = {"v1", "v2"}) - void tokenRefreshInvalidTokenAuthenticated(String apiVersion, Vertx vertx, VertxTestContext testContext) { + @CsvSource({"v1,asdf", "v2,asdf", "v1,invalidBase64%%%%", "v2,invalidBase64%%%%"}) + void tokenRefreshInvalidTokenAuthenticated(String apiVersion, String token, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; fakeAuth(clientSiteId, Role.GENERATOR); - sendTokenRefresh(apiVersion, vertx, ORIGIN_HEADER, "example.com", testContext, "abcd", "", 400, json -> { + sendTokenRefresh(apiVersion, vertx, ORIGIN_HEADER, "example.com", testContext, token, "", 400, json -> { assertEquals("invalid_token", json.getString("status")); assertTokenStatusMetrics( clientSiteId, From 73b9117fa1e25256e643aaad6f79790a09bfcd2a Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 12 Jul 2024 14:16:30 +1000 Subject: [PATCH 0593/1116] Building a Amazon Linux 2023 eif --- .github/actions/build_aws_eif/action.yaml | 5 +++- .../publish-aws-nitro-enclave-docker.yaml | 6 +++-- .../aws/pipeline/amazonlinux2023.Dockerfile | 26 +++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 scripts/aws/pipeline/amazonlinux2023.Dockerfile diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index cb9256567..ee55d156d 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -8,6 +8,9 @@ inputs: artifacts_base_output_dir: description: The base output directory for the AMI artifacts required: true + amazonlinux_dockerfile: + description: The Docker file to use to build the EIF + default: amazonlinux.Dockerfile outputs: enclave_id: @@ -21,7 +24,7 @@ runs: - name: Run amazonlinux Docker image shell: bash run: | - docker build -t amazonlinux -f ./scripts/aws/pipeline/amazonlinux.Dockerfile . + docker build -t amazonlinux -f ./scripts/aws/pipeline/${{ amazonlinux_dockerfile }} . docker run -d --privileged --name amazonlinux amazonlinux:latest - name: Create build folder diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 8a5ca215b..dab5282da 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -157,10 +157,11 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + amazonlinux_dockerfile: amazonlinux2023.Dockerfile - name: Check disk usage shell: bash @@ -216,10 +217,11 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + amazonlinux_dockerfile: amazonlinux2023.Dockerfile - name: Check disk usage shell: bash diff --git a/scripts/aws/pipeline/amazonlinux2023.Dockerfile b/scripts/aws/pipeline/amazonlinux2023.Dockerfile new file mode 100644 index 000000000..2914c9ee3 --- /dev/null +++ b/scripts/aws/pipeline/amazonlinux2023.Dockerfile @@ -0,0 +1,26 @@ +# https://gist.github.com/toricls/e17c7f2f1c024cc368dcd860804194f5 +FROM amazonlinux:2023 + +RUN dnf update -y + # systemd is not a hard requirement for Amazon ECS Anywhere, but the installation script currently only supports systemd to run. + # Amazon ECS Anywhere can be used without systemd, if you set up your nodes and register them into your ECS cluster **without** the installation script. +RUN dnf -y groupinstall "Development Tools" +RUN dnf -y install systemd vim-common wget git tar libstdc++-static.x86_64 cmake cmake3 aws-nitro-enclaves-cli aws-nitro-enclaves-cli-devel + +RUN systemctl enable docker + +RUN wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz \ + && echo "418a065fe1a4b8ace8fbf77c2da269a98f376e7115902e76cda7e741e4846a5d dante-1.4.3.tar.gz" > dante_checksum \ + && sha256sum --check dante_checksum \ + && tar -xf dante-1.4.3.tar.gz \ + && cd dante-1.4.3; ./configure; make; cd .. \ + && cp dante-1.4.3/sockd/sockd ./ + +RUN git clone https://github.com/IABTechLab/uid2-aws-enclave-vsockproxy.git \ + && mkdir uid2-aws-enclave-vsockproxy/build \ + && cd uid2-aws-enclave-vsockproxy/build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo; make; cd ../.. \ + && cp uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge ./vsockpx + +COPY ./scripts/aws/pipeline/aws_nitro_eif.sh /aws_nitro_eif.sh + +CMD ["/usr/sbin/init"] From 4d9427f9a9eaba03b6a3fb55a6dba42369f1bf85 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 12 Jul 2024 04:18:28 +0000 Subject: [PATCH 0594/1116] [CI Pipeline] Released Snapshot version: 5.37.120-alpha-227-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 88c5d6e3b..9d241a302 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.119 + 5.37.120-alpha-227-SNAPSHOT UTF-8 From 226cdaac3f463282ef0f25065b2a7493127b0efe Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Fri, 12 Jul 2024 14:27:06 +1000 Subject: [PATCH 0595/1116] Updated inputs --- .github/actions/build_aws_eif/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index ee55d156d..a63e37f30 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -24,7 +24,7 @@ runs: - name: Run amazonlinux Docker image shell: bash run: | - docker build -t amazonlinux -f ./scripts/aws/pipeline/${{ amazonlinux_dockerfile }} . + docker build -t amazonlinux -f ./scripts/aws/pipeline/${{ inputs.amazonlinux_dockerfile }} . docker run -d --privileged --name amazonlinux amazonlinux:latest - name: Create build folder From 99d00a89af3833bf9c0ff80d2786acaa86dd55bf Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 12 Jul 2024 04:27:53 +0000 Subject: [PATCH 0596/1116] [CI Pipeline] Released Snapshot version: 5.37.121-alpha-228-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d241a302..72c24cdc4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.120-alpha-227-SNAPSHOT + 5.37.121-alpha-228-SNAPSHOT UTF-8 From 4f83fe06640ca4fa8f203a8dc526006201de809e Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Fri, 12 Jul 2024 17:50:49 +0000 Subject: [PATCH 0597/1116] [CI Pipeline] Released Patch version: 5.37.123 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 88c5d6e3b..1e0856943 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.119 + 5.37.123 UTF-8 From b304fc0be8b7dffeee9f0f08a70f84fc04887aad Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 11:20:48 +1000 Subject: [PATCH 0598/1116] Added new pipeline to build EKS docker image --- .../publish-aws-eks-nitro-enclave-docker.yaml | 356 ++++++++++++++++++ scripts/aws/eks/Dockerfile | 19 + scripts/aws/eks/entrypoint.sh | 35 ++ 3 files changed, 410 insertions(+) create mode 100644 .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml create mode 100644 scripts/aws/eks/Dockerfile create mode 100644 scripts/aws/eks/entrypoint.sh diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml new file mode 100644 index 000000000..40867aacd --- /dev/null +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -0,0 +1,356 @@ +name: Publish EKS Operator +run-name: ${{ format('Publish {0} EKS Operator', inputs.release_type) }} +on: + workflow_dispatch: + inputs: + release_type: + type: choice + description: The type of release + options: + - Snapshot + - Patch + - Minor + - Major + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + type: string + default: '' + workflow_call: + inputs: + release_type: + description: The type of version number to return. Must be one of [Snapshot, Patch, Minor or Major] + required: true + type: string + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + type: string + default: '' + +env: + REGISTRY: ghcr.io + ENCLAVE_PROTOCOL: aws-nitro + DOCKER_CONTEXT_PATH: scripts/aws/eks + ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts + IMAGE_NAME: ${{ github.repository }} + +jobs: + start: + name: Update Operator Version + runs-on: ubuntu-latest + steps: + - name: Check branch and release type + id: checkRelease + uses: IABTechLab/uid2-shared-actions/actions/check_branch_and_release_type@v2 + with: + release_type: ${{ inputs.release_type }} + + - name: Approve Major release + if: inputs.release_type == 'Major' + uses: trstringer/manual-approval@v1 + with: + secret: ${{ github.token }} + approvers: thomasm-ttd,atarassov-ttd,cody-constine-ttd + minimum-approvals: 1 + issue-title: Creating Major version of UID2-Operator + + - name: Free up space - delete preinstalled tools + run: | + rm -rf /opt/hostedtoolcache + + - name: Show Context + run: | + printenv + echo "$GITHUB_CONTEXT" + shell: bash + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + IS_RELEASE: ${{ steps.checkRelease.outputs.is_release }} + + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Set version number + id: version + uses: IABTechLab/uid2-shared-actions/actions/version_number@v2 + with: + type: ${{ inputs.release_type }} + version_number: ${{ inputs.version_number_input }} + branch_name: ${{ github.ref }} + + - name: Update pom.xml + id: updatePom + run: | + current_version=$(grep -o '.*' pom.xml | head -1 | sed 's/\(.*\)<\/version>/\1/') + new_version=${{ steps.version.outputs.new_version }} + sed -i "0,/$current_version/s/$current_version/$new_version/" pom.xml + echo "Version number updated from $current_version to $new_version" + echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT + + - name: Commit pom.xml and version.json + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release != 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 + with: + add: 'pom.xml version.json' + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + + - name: Commit pom.xml, version.json and set tag + if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release == 'true' }} + uses: IABTechLab/uid2-shared-actions/actions/commit_pr_and_merge@v2 + with: + add: 'pom.xml version.json' + message: 'Released ${{ inputs.release_type }} version: ${{ steps.version.outputs.new_version }}' + tag: v${{ steps.version.outputs.new_version }} + + - name: Check disk usage + shell: bash + run: | + df -h + + outputs: + new_version: ${{ steps.version.outputs.new_version }} + is_release: ${{ steps.checkRelease.outputs.is_release }} + image_tag: ${{ steps.updatePom.outputs.image_tag }} + + buildUID2EIF: + name: Build UID2 EIF for EKS + runs-on: ubuntu-latest + needs: start + steps: + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Free up space - delete preinstalled tools + run: | + rm -rf /opt/hostedtoolcache + + - name: Check disk usage + shell: bash + run: | + df -h + + - name: Build UID2 AWS EIF for EKS + id: build_uid2_eif + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build + with: + identity_scope: uid2 + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + amazonlinux_dockerfile: amazonlinux2023.Dockerfile + + - name: Copy docker files + id: copy_docker_files + run: | + cp -r ./scripts/aws/eks ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + + - name: Check disk usage + shell: bash + run: | + df -h + + - name: Log in to the Docker container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=${{ needs.start.outputs.image_tag }} + + - name: Build and export to Docker + uses: docker/build-push-action@v5 + with: + context: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + load: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + JAR_VERSION=${{ needs.start.outputs.new_version }} + IMAGE_VERSION=${{ needs.start.outputs.new_version }} + BUILD_TARGET=${{ env.ENCLAVE_PROTOCOL }} + + - name: Push to Docker + id: push-to-docker + uses: docker/build-push-action@v5 + with: + context: ${{ env.DOCKER_CONTEXT_PATH }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + JAR_VERSION=${{ needs.start.outputs.new_version }} + IMAGE_VERSION=${{ needs.start.outputs.new_version }} + + + + #- name: Save UID2 eif artifact + # uses: actions/upload-artifact@v4 + # with: + # name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} + # path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + # if-no-files-found: error + + - name: Check disk usage + shell: bash + run: | + df -h + + outputs: + uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} + +# buildEUIDEIF: +# name: Build EUID EIF +# runs-on: ubuntu-latest +# needs: start +# steps: +# - name: Checkout full history on Main +# uses: actions/checkout@v4 +# if: ${{ inputs.version_number_input == '' }} +# with: +# fetch-depth: 0 +# +# - name: Checkout full history at tag v${{ inputs.version_number_input }} +# uses: actions/checkout@v4 +# if: ${{ inputs.version_number_input != '' }} +# with: +# ref: v${{ inputs.version_number_input }} +# fetch-depth: 0 +# +# - name: Restore timestamps +# uses: thetradedesk/git-restore-mtime-action@v1.3 +# +# - name: Free up space - delete preinstalled tools +# run: | +# rm -rf /opt/hostedtoolcache +# +# - name: Check disk usage +# shell: bash +# run: | +# df -h +# +# - name: Build EUID AWS EIF +# id: build_euid_eif +# uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build +# with: +# identity_scope: euid +# artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid +# amazonlinux_dockerfile: amazonlinux2023.Dockerfile +# +# - name: Check disk usage +# shell: bash +# run: | +# df -h +# +# - name: Save EUID eif artifact +# uses: actions/upload-artifact@v4 +# with: +# name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} +# path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid +# if-no-files-found: error +# +# - name: Check disk usage +# shell: bash +# run: | +# df -h +# +# outputs: +# euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} + + cleanup: + name: Cleanup Building AWS Image + runs-on: ubuntu-latest + needs: [start, buildUID2EIF] #, buildEUIDEIF] + steps: + - name: Check disk usage + shell: bash + run: | + df -h + + - name: Download UID2 artifacts + uses: actions/download-artifact@v4 + with: + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + + #- name: Download EUID artifacts + # uses: actions/download-artifact@v4 + # with: + # path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + + - name: Save Enclave Ids + run: | + mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests + echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + # echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt + + - name: Save Manifests as build artifacts + uses: actions/upload-artifact@v4 + with: + name: aws-enclave-ids-${{ needs.start.outputs.new_version }} + path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests + if-no-files-found: error + + - name: Generate release archive files + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + run: | + zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + # zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + + - name: Build changelog + id: github_release + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + uses: mikepenz/release-changelog-builder-action@v4 + with: + configurationJson: | + { + "template": "#{{CHANGELOG}}\n## Installation\n```\See [AWS Marketplace](https://unifiedid.com/docs/guides/operator-guide-aws-marketplace) for details\n```\n\n## Changelog\n#{{UNCATEGORIZED}}", + "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )" + } + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create release + if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + uses: softprops/action-gh-release@v2 + with: + name: ${{ needs.start.outputs.new_version }} + body: ${{ needs.start.outputs.github_changelog }} + draft: true + files: | + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt diff --git a/scripts/aws/eks/Dockerfile b/scripts/aws/eks/Dockerfile new file mode 100644 index 000000000..b64802eb1 --- /dev/null +++ b/scripts/aws/eks/Dockerfile @@ -0,0 +1,19 @@ +FROM amazonlinux:2023 +RUN yum install aws-nitro-enclaves-cli-devel jq -y +RUN dnf install aws-nitro-enclaves-cli -y +RUN yum install -y libxcrypt-compat + +RUN yum install -y python3 + +COPY ./sockd /home/ +COPY ./sockd.conf /etc/ +COPY ./python_enclave/uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge /home/vsockpx + +COPY ./entrypoint.sh /home/ +COPY ./uid2operator.eif /home/ +COPY ./proxies.host.yaml /home/proxies.host.yaml + +RUN chmod +x /home/vsockpx && chmod +x /home/entrypoint.sh +RUN yum install net-tools -y + +CMD ["/home/entrypoint.sh"] \ No newline at end of file diff --git a/scripts/aws/eks/entrypoint.sh b/scripts/aws/eks/entrypoint.sh new file mode 100644 index 000000000..c42965d69 --- /dev/null +++ b/scripts/aws/eks/entrypoint.sh @@ -0,0 +1,35 @@ +#!/bin/bash -eufx +CID=16 +EIF_PATH=/home/uid2operator.eif +MEMORY_MB=24576 +CPU_COUNT=6 + +function terminate_old_enclave() { + ENCLAVE_ID=$(nitro-cli describe-enclaves | jq -r ".[0].EnclaveID") + [ "$ENCLAVE_ID" != "null" ] && nitro-cli terminate-enclave --enclave-id ${ENCLAVE_ID} +} + +function setup_vsockproxy() { + VSOCK_PROXY=${VSOCK_PROXY:-/home/vsockpx} + VSOCK_CONFIG=${VSOCK_CONFIG:-/home/proxies.host.yaml} + VSOCK_THREADS=${VSOCK_THREADS:-$(( $(nproc) * 2 )) } + VSOCK_LOG_LEVEL=${VSOCK_LOG_LEVEL:-3} + echo "starting vsock proxy at $VSOCK_PROXY with $VSOCK_THREADS worker threads..." + $VSOCK_PROXY -c $VSOCK_CONFIG --workers $VSOCK_THREADS --log-level $VSOCK_LOG_LEVEL --daemon + echo "vsock proxy now running in background." +} + +function setup_dante() { + ulimit -n 1024 + /home/sockd -D +} + +function run_enclave() { + echo "starting enclave..." + nitro-cli run-enclave --cpu-count $CPU_COUNT --memory $MEMORY_MB --eif-path $EIF_PATH --enclave-cid $CID --enclave-name simple-eif --debug-mode --attach-console +} + +terminate_old_enclave +setup_vsockproxy +setup_dante +run_enclave \ No newline at end of file From 32bd7e8b6b21228cc2e0a21c459f9545132be878 Mon Sep 17 00:00:00 2001 From: asloob qureshi Date: Sun, 14 Jul 2024 18:52:20 -0700 Subject: [PATCH 0599/1116] Enable optout status API by default --- conf/default-config.json | 2 +- src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java | 2 +- src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/default-config.json b/conf/default-config.json index 44df29c6c..f8f1a2bcc 100644 --- a/conf/default-config.json +++ b/conf/default-config.json @@ -17,7 +17,7 @@ "optout_partition_interval": 86400, "optout_max_partitions": 30, "optout_heap_default_capacity": 8192, - "optout_status_api_enabled": false, + "optout_status_api_enabled": true, "optout_status_max_request_size": 5000, "cloud_download_threads": 8, "cloud_upload_threads": 2, diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index e43039380..5ca87cc37 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -407,7 +407,7 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, this.heap = new OptOutHeap(heapCapacity); this.adIdToOptOutTimestamp = Collections.emptyMap(); - this.optoutStatusApiEnabled = jsonConfig.getBoolean(Const.Config.OptOutStatusApiEnabled, false); + this.optoutStatusApiEnabled = jsonConfig.getBoolean(Const.Config.OptOutStatusApiEnabled, true); // initially 1 partition this.partitions = new OptOutPartition[1]; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 372935da7..59f2fd1ba 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -176,7 +176,7 @@ public UIDOperatorVerticle(JsonObject config, this.allowClockSkewSeconds = config.getInteger(Const.Config.AllowClockSkewSecondsProp, 1800); this.maxSharingLifetimeSeconds = config.getInteger(Const.Config.MaxSharingLifetimeProp, config.getInteger(Const.Config.SharingTokenExpiryProp)); this.saltRetrievalResponseHandler = saltRetrievalResponseHandler; - this.optOutStatusApiEnabled = config.getBoolean(Const.Config.OptOutStatusApiEnabled, false); + this.optOutStatusApiEnabled = config.getBoolean(Const.Config.OptOutStatusApiEnabled, true); this.optOutStatusMaxRequestSize = config.getInteger(Const.Config.OptOutStatusMaxRequestSize, 5000); } From 5d5525739f49784ea53c967ad722c66f6c42f826 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:00:51 +1000 Subject: [PATCH 0600/1116] Add pr trigger to register workflow --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index dab5282da..ade473bba 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -25,6 +25,7 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + pull_request: env: ENCLAVE_PROTOCOL: aws-nitro From 376e8327d087db29fe7ae04a9dc9a2ede4a31a18 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:08:09 +1000 Subject: [PATCH 0601/1116] Change trigger --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 1 + .github/workflows/publish-aws-nitro-enclave-docker.yaml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 40867aacd..d7b8f4be0 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -25,6 +25,7 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' + push: env: REGISTRY: ghcr.io diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ade473bba..dab5282da 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -25,7 +25,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - pull_request: env: ENCLAVE_PROTOCOL: aws-nitro From 7e3c98135cc9b0d1982654cfefc070ac5f83eded Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:10:30 +1000 Subject: [PATCH 0602/1116] Remove push trigger --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index d7b8f4be0..c5f1c9f64 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -6,6 +6,7 @@ on: release_type: type: choice description: The type of release + default: Snapshot options: - Snapshot - Patch @@ -25,7 +26,6 @@ on: description: If set, the version number will not be incremented and the given number will be used. type: string default: '' - push: env: REGISTRY: ghcr.io From e5d473cd830301b00ca3e2f4af7d38fc35e3657a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 04:11:33 +0000 Subject: [PATCH 0603/1116] [CI Pipeline] Released Snapshot version: 5.37.122-alpha-3-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 72c24cdc4..c2b2d20d1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.121-alpha-228-SNAPSHOT + 5.37.122-alpha-3-SNAPSHOT UTF-8 From 6ca3824aaca6d8f726a1da00ee724cba62e360a1 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:30:12 +1000 Subject: [PATCH 0604/1116] Check folder contents --- .../publish-aws-eks-nitro-enclave-docker.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index c5f1c9f64..0f2e19a11 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -159,18 +159,19 @@ jobs: run: | df -h - - name: Build UID2 AWS EIF for EKS - id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build - with: - identity_scope: uid2 - artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - amazonlinux_dockerfile: amazonlinux2023.Dockerfile + #- name: Build UID2 AWS EIF for EKS + # id: build_uid2_eif + # uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build + # with: + # identity_scope: uid2 + # artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + # amazonlinux_dockerfile: amazonlinux2023.Dockerfile - name: Copy docker files id: copy_docker_files run: | cp -r ./scripts/aws/eks ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + ls -l ./scripts/aws/eks - name: Check disk usage shell: bash From d331d1d6204fea59f091c6ef0f008eef58c3be09 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 04:30:56 +0000 Subject: [PATCH 0605/1116] [CI Pipeline] Released Snapshot version: 5.37.123-alpha-4-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c2b2d20d1..3c4dc2085 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.122-alpha-3-SNAPSHOT + 5.37.123-alpha-4-SNAPSHOT UTF-8 From c039eeeeca4d64313163a7400f82e7efe2a758fa Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:39:35 +1000 Subject: [PATCH 0606/1116] Create output dir --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 0f2e19a11..753654804 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -170,6 +170,7 @@ jobs: - name: Copy docker files id: copy_docker_files run: | + mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 cp -r ./scripts/aws/eks ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 ls -l ./scripts/aws/eks From b1318bcdce1f02d114dec78c679df5a35e57ef13 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 04:40:40 +0000 Subject: [PATCH 0607/1116] [CI Pipeline] Released Snapshot version: 5.37.124-alpha-5-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3c4dc2085..c28feb03f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.123-alpha-4-SNAPSHOT + 5.37.124-alpha-5-SNAPSHOT UTF-8 From d2fbca3f54d4b0025801a4fcbf4d93678f9a70c5 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:47:27 +1000 Subject: [PATCH 0608/1116] Check contents of folder --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 753654804..bd4c85b74 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -173,6 +173,7 @@ jobs: mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 cp -r ./scripts/aws/eks ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 ls -l ./scripts/aws/eks + ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - name: Check disk usage shell: bash From 11b92a0e5ab91bf444c39a688f815d695110c387 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 04:48:12 +0000 Subject: [PATCH 0609/1116] [CI Pipeline] Released Snapshot version: 5.37.125-alpha-6-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c28feb03f..120102472 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.124-alpha-5-SNAPSHOT + 5.37.125-alpha-6-SNAPSHOT UTF-8 From 025388bf161a89b553f854de924498fe817f6421 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:55:36 +1000 Subject: [PATCH 0610/1116] Updated file copy --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index bd4c85b74..e953ba3cf 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -171,7 +171,7 @@ jobs: id: copy_docker_files run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - cp -r ./scripts/aws/eks ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + cp -r ./scripts/aws/eks/* ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 ls -l ./scripts/aws/eks ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 From 10264ec437f88883d7fbaad58ec94ba23e226302 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 04:56:27 +0000 Subject: [PATCH 0611/1116] [CI Pipeline] Released Snapshot version: 5.37.126-alpha-7-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 120102472..5c0327336 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.125-alpha-6-SNAPSHOT + 5.37.126-alpha-7-SNAPSHOT UTF-8 From db505784139527f61d026d5ed686c0f5da46fb21 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 14:59:25 +1000 Subject: [PATCH 0612/1116] Add back the eif build --- .../publish-aws-eks-nitro-enclave-docker.yaml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index e953ba3cf..65e8c553a 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -159,21 +159,19 @@ jobs: run: | df -h - #- name: Build UID2 AWS EIF for EKS - # id: build_uid2_eif - # uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build - # with: - # identity_scope: uid2 - # artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - # amazonlinux_dockerfile: amazonlinux2023.Dockerfile + - name: Build UID2 AWS EIF for EKS + id: build_uid2_eif + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build + with: + identity_scope: uid2 + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + amazonlinux_dockerfile: amazonlinux2023.Dockerfile - name: Copy docker files id: copy_docker_files run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 cp -r ./scripts/aws/eks/* ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - ls -l ./scripts/aws/eks - ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - name: Check disk usage shell: bash From d5368f0589f93a17cdd34ed07c352da9943eba3b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 05:00:09 +0000 Subject: [PATCH 0613/1116] [CI Pipeline] Released Snapshot version: 5.37.127-alpha-8-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c0327336..e5492567a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.126-alpha-7-SNAPSHOT + 5.37.127-alpha-8-SNAPSHOT UTF-8 From ea3a8b932cb7f3dd724d7cd7af83ecba27ab0ade Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 05:25:06 +0000 Subject: [PATCH 0614/1116] [CI Pipeline] Released Snapshot version: 5.37.128-alpha-9-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e5492567a..af0fe43bd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.127-alpha-8-SNAPSHOT + 5.37.128-alpha-9-SNAPSHOT UTF-8 From b6482969fea3a0a421cd1df85d548e20496dad05 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 15:35:59 +1000 Subject: [PATCH 0615/1116] Updated docker build --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 1 + scripts/aws/eks/Dockerfile | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 65e8c553a..49f2c14c9 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -172,6 +172,7 @@ jobs: run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 cp -r ./scripts/aws/eks/* ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - name: Check disk usage shell: bash diff --git a/scripts/aws/eks/Dockerfile b/scripts/aws/eks/Dockerfile index b64802eb1..d4679c4d7 100644 --- a/scripts/aws/eks/Dockerfile +++ b/scripts/aws/eks/Dockerfile @@ -1,19 +1,19 @@ FROM amazonlinux:2023 RUN yum install aws-nitro-enclaves-cli-devel jq -y RUN dnf install aws-nitro-enclaves-cli -y -RUN yum install -y libxcrypt-compat +# RUN yum install -y libxcrypt-compat RUN yum install -y python3 COPY ./sockd /home/ COPY ./sockd.conf /etc/ -COPY ./python_enclave/uid2-aws-enclave-vsockproxy/build/vsock-bridge/src/vsock-bridge /home/vsockpx +COPY ./vsockpx /home COPY ./entrypoint.sh /home/ COPY ./uid2operator.eif /home/ COPY ./proxies.host.yaml /home/proxies.host.yaml RUN chmod +x /home/vsockpx && chmod +x /home/entrypoint.sh -RUN yum install net-tools -y +# RUN yum install net-tools -y CMD ["/home/entrypoint.sh"] \ No newline at end of file From 3a892c00fa16414d2c738efd6dfde8a3e09b3ea4 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 05:48:45 +0000 Subject: [PATCH 0616/1116] [CI Pipeline] Released Snapshot version: 5.37.129-alpha-10-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af0fe43bd..3020f7685 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.128-alpha-9-SNAPSHOT + 5.37.129-alpha-10-SNAPSHOT UTF-8 From 33db92b84c23d9088bbc902f3bf795d04fca1990 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Mon, 15 Jul 2024 16:11:50 +1000 Subject: [PATCH 0617/1116] Updated context for docker push --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 49f2c14c9..e04e5e901 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -210,7 +210,7 @@ jobs: id: push-to-docker uses: docker/build-push-action@v5 with: - context: ${{ env.DOCKER_CONTEXT_PATH }} + context: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From eb26d28a8fe17bbd39d9aa1ae2c20d23890aab1a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 06:15:36 +0000 Subject: [PATCH 0618/1116] [CI Pipeline] Released Snapshot version: 5.37.130-alpha-11-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3020f7685..47dfc3539 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.129-alpha-10-SNAPSHOT + 5.37.130-alpha-11-SNAPSHOT UTF-8 From d2387f0068ace2337c1dea10567a59a720b74b4c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 09:53:44 +1000 Subject: [PATCH 0619/1116] Refactored into shared action --- .../build_eks_docker_image/action.yaml | 121 +++++++++++ .../publish-aws-eks-nitro-enclave-docker.yaml | 196 +++--------------- 2 files changed, 148 insertions(+), 169 deletions(-) create mode 100644 .github/actions/build_eks_docker_image/action.yaml diff --git a/.github/actions/build_eks_docker_image/action.yaml b/.github/actions/build_eks_docker_image/action.yaml new file mode 100644 index 000000000..0e2c42f24 --- /dev/null +++ b/.github/actions/build_eks_docker_image/action.yaml @@ -0,0 +1,121 @@ +name: Build AWS EKS Docker Image +description: Builds the docker images to use as a EKS Pod. Includes building the EIF + +inputs: + version_number_input: + description: If set, the version number will not be incremented and the given number will be used. + default: '' + identity_scope: + description: The identity scope [uid2, euid] + required: true + artifacts_output_dir: + description: The output directory for the artifacts + required: true + image_tag: + description: The Tag to give the docker image + required: true + new_version: + description: The new version number after potentially updating the POM + required: true + +outputs: + enclave_id: + description: The enclave id for this EIF. + value: ${{ steps.build_aws_eif.outputs.enclave_id }} + +runs: + using: "composite" + + steps: + - name: Checkout full history on Main + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input == '' }} + with: + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Checkout full history at tag v${{ inputs.version_number_input }} + uses: actions/checkout@v4 + if: ${{ inputs.version_number_input != '' }} + with: + ref: v${{ inputs.version_number_input }} + # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. + fetch-depth: 0 + + - name: Restore timestamps + uses: thetradedesk/git-restore-mtime-action@v1.3 + + - name: Free up space - delete preinstalled tools + shell: bash + run: | + rm -rf /opt/hostedtoolcache + + - name: Check disk usage + shell: bash + run: | + df -h + + - name: Build AWS EIF for EKS + id: build_aws_eif + uses: ./.github/actions/build_aws_eif + with: + identity_scope: ${{ inputs.identity_scope }} + artifacts_output_dir: ${{ inputs.artifacts_output_dir }} + amazonlinux_dockerfile: amazonlinux2023.Dockerfile + + - name: Copy docker files + shell: bash + id: copy_docker_files + run: | + mkdir -p ${{ inputs.artifacts_output_dir }} + cp -r ./scripts/aws/eks/* ${{ inputs.artifacts_output_dir }} + ls -l ${{ inputs.artifacts_output_dir }} + + - name: Check disk usage + shell: bash + run: | + df -h + + - name: Log in to the Docker container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=${{ inputs.image_tag }} + + - name: Build and export to Docker + uses: docker/build-push-action@v5 + with: + context: ${{ inputs.artifacts_output_dir }} + load: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + JAR_VERSION=${{ inputs.new_version }} + IMAGE_VERSION=${{ inputs.new_version }} + BUILD_TARGET=${{ env.ENCLAVE_PROTOCOL }} + + - name: Push to Docker + id: push-to-docker + uses: docker/build-push-action@v5 + with: + context: ${{ inputs.artifacts_output_dir }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + JAR_VERSION=${{ inputs.new_version }} + IMAGE_VERSION=${{ inputs.new_version }} + + - name: Check disk usage + shell: bash + run: | + df -h diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index e04e5e901..81cf4b472 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -132,197 +132,55 @@ jobs: runs-on: ubuntu-latest needs: start steps: - - name: Checkout full history on Main - uses: actions/checkout@v4 - if: ${{ inputs.version_number_input == '' }} - with: - # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. - fetch-depth: 0 - - - name: Checkout full history at tag v${{ inputs.version_number_input }} - uses: actions/checkout@v4 - if: ${{ inputs.version_number_input != '' }} - with: - ref: v${{ inputs.version_number_input }} - # git-restore-mtime requires full git history. The default fetch-depth value (1) creates a shallow checkout. - fetch-depth: 0 - - - name: Restore timestamps - uses: thetradedesk/git-restore-mtime-action@v1.3 - - - name: Free up space - delete preinstalled tools - run: | - rm -rf /opt/hostedtoolcache - - - name: Check disk usage - shell: bash - run: | - df -h - - - name: Build UID2 AWS EIF for EKS - id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build + - name: Build Docker Image for EKS Pod + id: build_docker_image + uses: ./.github/actions/build_eks_docker_image with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - amazonlinux_dockerfile: amazonlinux2023.Dockerfile - - - name: Copy docker files - id: copy_docker_files - run: | - mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - cp -r ./scripts/aws/eks/* ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - ls -l ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - - - name: Check disk usage - shell: bash - run: | - df -h - - - name: Log in to the Docker container registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=raw,value=${{ needs.start.outputs.image_tag }} - - - name: Build and export to Docker - uses: docker/build-push-action@v5 - with: - context: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - load: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - JAR_VERSION=${{ needs.start.outputs.new_version }} - IMAGE_VERSION=${{ needs.start.outputs.new_version }} - BUILD_TARGET=${{ env.ENCLAVE_PROTOCOL }} - - - name: Push to Docker - id: push-to-docker - uses: docker/build-push-action@v5 - with: - context: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - JAR_VERSION=${{ needs.start.outputs.new_version }} - IMAGE_VERSION=${{ needs.start.outputs.new_version }} - - - - #- name: Save UID2 eif artifact - # uses: actions/upload-artifact@v4 - # with: - # name: aws-uid2-deployment-files-${{ needs.start.outputs.new_version }} - # path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - # if-no-files-found: error - - - name: Check disk usage - shell: bash - run: | - df -h - + version_number_input: ${{ inputs.version_number_input }} + image_tag: ${{ needs.start.outputs.image_tag }} + new_version: ${{ needs.start.outputs.new_version }} outputs: - uid2_enclave_id: ${{ steps.build_uid2_eif.outputs.enclave_id }} + uid2_enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} -# buildEUIDEIF: -# name: Build EUID EIF -# runs-on: ubuntu-latest -# needs: start -# steps: -# - name: Checkout full history on Main -# uses: actions/checkout@v4 -# if: ${{ inputs.version_number_input == '' }} -# with: -# fetch-depth: 0 -# -# - name: Checkout full history at tag v${{ inputs.version_number_input }} -# uses: actions/checkout@v4 -# if: ${{ inputs.version_number_input != '' }} -# with: -# ref: v${{ inputs.version_number_input }} -# fetch-depth: 0 -# -# - name: Restore timestamps -# uses: thetradedesk/git-restore-mtime-action@v1.3 -# -# - name: Free up space - delete preinstalled tools -# run: | -# rm -rf /opt/hostedtoolcache -# -# - name: Check disk usage -# shell: bash -# run: | -# df -h -# -# - name: Build EUID AWS EIF -# id: build_euid_eif -# uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build -# with: -# identity_scope: euid -# artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid -# amazonlinux_dockerfile: amazonlinux2023.Dockerfile -# -# - name: Check disk usage -# shell: bash -# run: | -# df -h -# -# - name: Save EUID eif artifact -# uses: actions/upload-artifact@v4 -# with: -# name: aws-euid-deployment-files-${{ needs.start.outputs.new_version }} -# path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid -# if-no-files-found: error -# -# - name: Check disk usage -# shell: bash -# run: | -# df -h -# -# outputs: -# euid_enclave_id: ${{ steps.build_euid_eif.outputs.enclave_id }} + buildEUIDEIF: + name: Build EUID EIF for EKS + runs-on: ubuntu-latest + needs: start + steps: + - name: Build Docker Image for EKS Pod + id: build_docker_image + uses: ./.github/actions/build_eks_docker_image + with: + identity_scope: euid + artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + version_number_input: ${{ inputs.version_number_input }} + image_tag: ${{ needs.start.outputs.image_tag }} + new_version: ${{ needs.start.outputs.new_version }} + outputs: + uid2_enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} cleanup: name: Cleanup Building AWS Image runs-on: ubuntu-latest - needs: [start, buildUID2EIF] #, buildEUIDEIF] + needs: [start, buildUID2EIF, buildEUIDEIF] steps: - name: Check disk usage shell: bash run: | df -h - - name: Download UID2 artifacts - uses: actions/download-artifact@v4 - with: - path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - - #- name: Download EUID artifacts - # uses: actions/download-artifact@v4 - # with: - # path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt - # echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-eks-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-eks-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 with: - name: aws-enclave-ids-${{ needs.start.outputs.new_version }} + name: aws-eks-enclave-ids-${{ needs.start.outputs.new_version }} path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests if-no-files-found: error From 05fb6676666f152e12a9d645927db410f9f5ed8e Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 15 Jul 2024 23:54:36 +0000 Subject: [PATCH 0620/1116] [CI Pipeline] Released Snapshot version: 5.37.131-alpha-12-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 47dfc3539..379df1005 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.130-alpha-11-SNAPSHOT + 5.37.131-alpha-12-SNAPSHOT UTF-8 From 1fe6744dc39597ac35d705e00370a294e007320c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 09:59:02 +1000 Subject: [PATCH 0621/1116] Changed action reference --- .../publish-aws-eks-nitro-enclave-docker.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 81cf4b472..d76d1b392 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -134,15 +134,15 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: ./.github/actions/build_eks_docker_image + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build with: identity_scope: uid2 - artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 + artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 version_number_input: ${{ inputs.version_number_input }} image_tag: ${{ needs.start.outputs.image_tag }} new_version: ${{ needs.start.outputs.new_version }} outputs: - uid2_enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} + enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} buildEUIDEIF: name: Build EUID EIF for EKS @@ -151,15 +151,15 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: ./.github/actions/build_eks_docker_image + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build with: identity_scope: euid - artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid + artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid version_number_input: ${{ inputs.version_number_input }} image_tag: ${{ needs.start.outputs.image_tag }} new_version: ${{ needs.start.outputs.new_version }} outputs: - uid2_enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} + enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} cleanup: name: Cleanup Building AWS Image @@ -174,8 +174,8 @@ jobs: - name: Save Enclave Ids run: | mkdir -p ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests - echo ${{ needs.buildUID2EIF.outputs.uid2_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-eks-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt - echo ${{ needs.buildEUIDEIF.outputs.euid_enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-eks-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ needs.buildUID2EIF.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-eks-uid2-enclave-id-${{ needs.start.outputs.new_version }}.txt + echo ${{ needs.buildEUIDEIF.outputs.enclave_id }} >> ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests/aws-eks-euid-enclave-id-${{ needs.start.outputs.new_version }}.txt - name: Save Manifests as build artifacts uses: actions/upload-artifact@v4 From 5b67ad0055af5e036f0c6f1e2a27917dec39934d Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 00:00:18 +0000 Subject: [PATCH 0622/1116] [CI Pipeline] Released Snapshot version: 5.37.132-alpha-13-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 379df1005..73c24811f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.131-alpha-12-SNAPSHOT + 5.37.132-alpha-13-SNAPSHOT UTF-8 From e663d969ca746ad6726d08873f9efd5db1a94dc4 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 10:03:59 +1000 Subject: [PATCH 0623/1116] Pass github token to action --- .github/actions/build_eks_docker_image/action.yaml | 4 +++- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/actions/build_eks_docker_image/action.yaml b/.github/actions/build_eks_docker_image/action.yaml index 0e2c42f24..82d831aa3 100644 --- a/.github/actions/build_eks_docker_image/action.yaml +++ b/.github/actions/build_eks_docker_image/action.yaml @@ -17,6 +17,8 @@ inputs: new_version: description: The new version number after potentially updating the POM required: true + github_token: + description: The GitHub token used to login to Docker outputs: enclave_id: @@ -81,7 +83,7 @@ runs: with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ inputs.github_token }} - name: Extract metadata (tags, labels) for Docker id: meta diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index d76d1b392..09ef20a02 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -141,6 +141,7 @@ jobs: version_number_input: ${{ inputs.version_number_input }} image_tag: ${{ needs.start.outputs.image_tag }} new_version: ${{ needs.start.outputs.new_version }} + github_token: $${{ secrets.GITHUB_TOKEN }} outputs: enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} @@ -158,6 +159,7 @@ jobs: version_number_input: ${{ inputs.version_number_input }} image_tag: ${{ needs.start.outputs.image_tag }} new_version: ${{ needs.start.outputs.new_version }} + github_token: $${{ secrets.GITHUB_TOKEN }} outputs: enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} From 8478837c1c6f7dc3f7de572318f99d1e43b32ef2 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 10:05:23 +1000 Subject: [PATCH 0624/1116] Make token required --- .github/actions/build_eks_docker_image/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/build_eks_docker_image/action.yaml b/.github/actions/build_eks_docker_image/action.yaml index 82d831aa3..6c5fa6303 100644 --- a/.github/actions/build_eks_docker_image/action.yaml +++ b/.github/actions/build_eks_docker_image/action.yaml @@ -19,6 +19,7 @@ inputs: required: true github_token: description: The GitHub token used to login to Docker + required: true outputs: enclave_id: From 16f3c3ff4f931c8e462ce7bd6541fc69d915850f Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 00:06:13 +0000 Subject: [PATCH 0625/1116] [CI Pipeline] Released Snapshot version: 5.37.133-alpha-14-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 73c24811f..6d5423648 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.132-alpha-13-SNAPSHOT + 5.37.133-alpha-14-SNAPSHOT UTF-8 From 47db54f54ab15ac668874ea458cf1930a889f8bc Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 10:24:37 +1000 Subject: [PATCH 0626/1116] Corrected parameter name --- .github/actions/build_eks_docker_image/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_eks_docker_image/action.yaml b/.github/actions/build_eks_docker_image/action.yaml index 6c5fa6303..7ab10e9d9 100644 --- a/.github/actions/build_eks_docker_image/action.yaml +++ b/.github/actions/build_eks_docker_image/action.yaml @@ -63,7 +63,7 @@ runs: uses: ./.github/actions/build_aws_eif with: identity_scope: ${{ inputs.identity_scope }} - artifacts_output_dir: ${{ inputs.artifacts_output_dir }} + artifacts_base_output_dir: ${{ inputs.artifacts_output_dir }} amazonlinux_dockerfile: amazonlinux2023.Dockerfile - name: Copy docker files From a7747c0d226489600b3d3a7eff736ca4c8885f1b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 00:25:31 +0000 Subject: [PATCH 0627/1116] [CI Pipeline] Released Snapshot version: 5.37.134-alpha-15-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6d5423648..fddb22f35 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.133-alpha-14-SNAPSHOT + 5.37.134-alpha-15-SNAPSHOT UTF-8 From 4cd93aa315bbe3a650208f219979452c75d65d64 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 10:54:54 +1000 Subject: [PATCH 0628/1116] Add permissions to job --- .../publish-aws-eks-nitro-enclave-docker.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 09ef20a02..5a8bba108 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -100,7 +100,7 @@ jobs: new_version=${{ steps.version.outputs.new_version }} sed -i "0,/$current_version/s/$current_version/$new_version/" pom.xml echo "Version number updated from $current_version to $new_version" - echo "image_tag=${{ steps.version.outputs.new_version }}-${{ env.ENCLAVE_PROTOCOL }}" >> $GITHUB_OUTPUT + echo "image_tag=${{ steps.version.outputs.new_version }}-eks-nitro" >> $GITHUB_OUTPUT - name: Commit pom.xml and version.json if: ${{ inputs.version_number_input == '' && steps.checkRelease.outputs.is_release != 'true' }} @@ -130,6 +130,10 @@ jobs: buildUID2EIF: name: Build UID2 EIF for EKS runs-on: ubuntu-latest + permissions: + contents: write + security-events: write + packages: write needs: start steps: - name: Build Docker Image for EKS Pod @@ -148,6 +152,10 @@ jobs: buildEUIDEIF: name: Build EUID EIF for EKS runs-on: ubuntu-latest + permissions: + contents: write + security-events: write + packages: write needs: start steps: - name: Build Docker Image for EKS Pod From e1a1c2544b43f11d9beb27e8b7553b4acefa470a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 00:55:45 +0000 Subject: [PATCH 0629/1116] [CI Pipeline] Released Snapshot version: 5.37.135-alpha-16-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fddb22f35..59a37b265 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.134-alpha-15-SNAPSHOT + 5.37.135-alpha-16-SNAPSHOT UTF-8 From 74e98d4cb5ac2e05963f1d892249398ba292311c Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 11:10:59 +1000 Subject: [PATCH 0630/1116] Typo in token --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 5a8bba108..80a307906 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -145,7 +145,7 @@ jobs: version_number_input: ${{ inputs.version_number_input }} image_tag: ${{ needs.start.outputs.image_tag }} new_version: ${{ needs.start.outputs.new_version }} - github_token: $${{ secrets.GITHUB_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} outputs: enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} @@ -167,7 +167,7 @@ jobs: version_number_input: ${{ inputs.version_number_input }} image_tag: ${{ needs.start.outputs.image_tag }} new_version: ${{ needs.start.outputs.new_version }} - github_token: $${{ secrets.GITHUB_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} outputs: enclave_id: ${{ steps.build_docker_image.outputs.enclave_id }} From d23175b1c9e55760de287292c46acb6a9a9a815b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 01:11:45 +0000 Subject: [PATCH 0631/1116] [CI Pipeline] Released Snapshot version: 5.37.136-alpha-17-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 59a37b265..d0dbe83f1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.135-alpha-16-SNAPSHOT + 5.37.136-alpha-17-SNAPSHOT UTF-8 From 2b7aa4730386b6bf1018cab71824e60a7a83845d Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 11:46:07 +1000 Subject: [PATCH 0632/1116] Update docker image name to include eks --- .github/actions/build_eks_docker_image/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_eks_docker_image/action.yaml b/.github/actions/build_eks_docker_image/action.yaml index 7ab10e9d9..dfc8fdcbe 100644 --- a/.github/actions/build_eks_docker_image/action.yaml +++ b/.github/actions/build_eks_docker_image/action.yaml @@ -90,7 +90,7 @@ runs: id: meta uses: docker/metadata-action@v5 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-eks-${{ inputs.identity_scope }} tags: | type=raw,value=${{ inputs.image_tag }} From d906855b4725e0ccb083290ea5eb2f460806b6d8 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 01:47:01 +0000 Subject: [PATCH 0633/1116] [CI Pipeline] Released Snapshot version: 5.37.137-alpha-18-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d0dbe83f1..ece2557ef 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.136-alpha-17-SNAPSHOT + 5.37.137-alpha-18-SNAPSHOT UTF-8 From d375e263ede4392047a818df4d65978f00ea267b Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 12:46:00 +1000 Subject: [PATCH 0634/1116] Change branch ref to main --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 4 ++-- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 80a307906..db0cb4d54 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -138,7 +138,7 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@main with: identity_scope: uid2 artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -160,7 +160,7 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@main with: identity_scope: euid artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index dab5282da..39fc1baec 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -157,7 +157,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -217,7 +217,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3706-eks-eif-build + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 0bd49cf358cbcdfbc0412f0c05f90ce527249003 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 12:48:42 +1000 Subject: [PATCH 0635/1116] Revert docker image for AMI build --- .github/workflows/publish-aws-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index 39fc1baec..b20d2de12 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -161,7 +161,7 @@ jobs: with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - amazonlinux_dockerfile: amazonlinux2023.Dockerfile + amazonlinux_dockerfile: amazonlinux.Dockerfile - name: Check disk usage shell: bash @@ -221,7 +221,7 @@ jobs: with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - amazonlinux_dockerfile: amazonlinux2023.Dockerfile + amazonlinux_dockerfile: amazonlinux.Dockerfile - name: Check disk usage shell: bash From afc06bc08da8e5621767479e20e2a87ee0678616 Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Tue, 16 Jul 2024 14:29:55 +1000 Subject: [PATCH 0636/1116] Added new files for EKS eif --- .github/actions/build_aws_eif/action.yaml | 7 +- .../build_eks_docker_image/action.yaml | 7 +- .../publish-aws-eks-nitro-enclave-docker.yaml | 5 +- .../publish-aws-nitro-enclave-docker.yaml | 6 +- Makefile.eks | 92 ++++++++++++++ scripts/aws/eks/enclave/Dockerfile | 49 ++++++++ scripts/aws/eks/enclave/entrypoint.sh | 115 ++++++++++++++++++ scripts/aws/eks/enclave/proxies.nitro.yaml | 26 ++++ scripts/aws/eks/{ => pod}/Dockerfile | 0 scripts/aws/eks/{ => pod}/entrypoint.sh | 0 scripts/aws/eks/pod/proxies.host.yaml | 21 ++++ 11 files changed, 318 insertions(+), 10 deletions(-) create mode 100644 Makefile.eks create mode 100644 scripts/aws/eks/enclave/Dockerfile create mode 100644 scripts/aws/eks/enclave/entrypoint.sh create mode 100644 scripts/aws/eks/enclave/proxies.nitro.yaml rename scripts/aws/eks/{ => pod}/Dockerfile (100%) rename scripts/aws/eks/{ => pod}/entrypoint.sh (100%) create mode 100644 scripts/aws/eks/pod/proxies.host.yaml diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index a63e37f30..b212db8d1 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -11,6 +11,9 @@ inputs: amazonlinux_dockerfile: description: The Docker file to use to build the EIF default: amazonlinux.Dockerfile + makefile: + description: The make file to use + default: Makefile.nitro outputs: enclave_id: @@ -24,7 +27,7 @@ runs: - name: Run amazonlinux Docker image shell: bash run: | - docker build -t amazonlinux -f ./scripts/aws/pipeline/${{ inputs.amazonlinux_dockerfile }} . + docker build -t amazonlinux -f ${{ inputs.amazonlinux_dockerfile }} . docker run -d --privileged --name amazonlinux amazonlinux:latest - name: Create build folder @@ -50,7 +53,7 @@ runs: - name: Build EIF shell: bash run: | - make -f Makefile.nitro ${{ inputs.identity_scope }}operator.eif + make -f ${{ inputs.makefile }} ${{ inputs.identity_scope }}operator.eif - name: Free up space shell: bash diff --git a/.github/actions/build_eks_docker_image/action.yaml b/.github/actions/build_eks_docker_image/action.yaml index dfc8fdcbe..556543751 100644 --- a/.github/actions/build_eks_docker_image/action.yaml +++ b/.github/actions/build_eks_docker_image/action.yaml @@ -64,14 +64,15 @@ runs: with: identity_scope: ${{ inputs.identity_scope }} artifacts_base_output_dir: ${{ inputs.artifacts_output_dir }} - amazonlinux_dockerfile: amazonlinux2023.Dockerfile + amazonlinux_dockerfile: ./scripts/aws/pipeline/amazonlinux2023.Dockerfile + makefile: Makefile.eks - - name: Copy docker files + - name: Copy docker files for the Operator Pod shell: bash id: copy_docker_files run: | mkdir -p ${{ inputs.artifacts_output_dir }} - cp -r ./scripts/aws/eks/* ${{ inputs.artifacts_output_dir }} + cp -r ./scripts/aws/eks/pod/* ${{ inputs.artifacts_output_dir }} ls -l ${{ inputs.artifacts_output_dir }} - name: Check disk usage diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index db0cb4d54..356eefdc0 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -30,7 +30,6 @@ on: env: REGISTRY: ghcr.io ENCLAVE_PROTOCOL: aws-nitro - DOCKER_CONTEXT_PATH: scripts/aws/eks ARTIFACTS_BASE_OUTPUT_DIR: ${{ github.workspace }}/deployment-artifacts IMAGE_NAME: ${{ github.repository }} @@ -138,7 +137,7 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@main + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build with: identity_scope: uid2 artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -160,7 +159,7 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@main + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build with: identity_scope: euid artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index b20d2de12..ff7fb0375 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -161,7 +161,8 @@ jobs: with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 - amazonlinux_dockerfile: amazonlinux.Dockerfile + amazonlinux_dockerfile: ./scripts/aws/pipeline/amazonlinux.Dockerfile + makefile: Makefile.nitro - name: Check disk usage shell: bash @@ -221,7 +222,8 @@ jobs: with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid - amazonlinux_dockerfile: amazonlinux.Dockerfile + amazonlinux_dockerfile: ./scripts/aws/pipeline/amazonlinux.Dockerfile + makefile: Makefile.nitro - name: Check disk usage shell: bash diff --git a/Makefile.eks b/Makefile.eks new file mode 100644 index 000000000..262127d5d --- /dev/null +++ b/Makefile.eks @@ -0,0 +1,92 @@ +CONFIG_DIR=/etc/uid2operator +DATA_DIR=/opt/uid2operator + +.PHONY: all + +all: build_eif + +################################################################################################################################################################## + +# EIF + +.PHONY: build_eif + +build_eif: uid2operator.eif euidoperator.eif + +uid2operator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/syslog-ng-core_4.6.0-1_amd64.deb build/syslog-ng-ose-pub.asc build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py + cd build; docker build -t uid2operator . --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./uid2operator.tar uid2operator; docker cp ./uid2operator.tar amazonlinux:/uid2operator.tar + docker exec amazonlinux bash aws_nitro_eif.sh uid2operator + +euidoperator.eif: build_artifacts build_configs build/proxies.nitro.yaml build/syslog-ng-client.conf build/syslog-ng-core_4.6.0-1_amd64.deb build/syslog-ng-ose-pub.asc build/entrypoint.sh build/vsockpx build/Dockerfile build/load_config.py build/make_config.py + cd build; docker build -t euidoperator . --build-arg IDENTITY_SCOPE='EUID' --build-arg JAR_VERSION=`cat package.version` --build-arg IMAGE_VERSION=`cat package.version`-`git show --format="%h" --no-patch`; docker save -o ./euidoperator.tar euidoperator; docker cp ./euidoperator.tar amazonlinux:/euidoperator.tar + docker exec amazonlinux bash aws_nitro_eif.sh euidoperator + +################################################################################################################################################################## + +# Config scripts + +build/load_config.py: ./scripts/aws/load_config.py + cp ./scripts/aws/load_config.py ./build/ + +build/make_config.py: ./scripts/aws/make_config.py + cp ./scripts/aws/make_config.py ./build/ + +################################################################################################################################################################## + +# Configs + +.PHONY: build_configs + +build_configs: build/conf/default-config.json build/conf/prod-uid2-config.json build/conf/integ-uid2-config.json build/conf/prod-euid-config.json build/conf/integ-euid-config.json build/conf/logback.xml + +build/conf/default-config.json: build_artifacts ./scripts/aws/conf/default-config.json + cp ./scripts/aws/conf/default-config.json ./build/conf/ + +build/conf/prod-uid2-config.json: build_artifacts ./scripts/aws/conf/prod-uid2-config.json + cp ./scripts/aws/conf/prod-uid2-config.json ./build/conf/ + +build/conf/prod-euid-config.json: build_artifacts ./scripts/aws/conf/prod-euid-config.json + cp ./scripts/aws/conf/prod-euid-config.json ./build/conf/ + +build/conf/integ-uid2-config.json: build_artifacts ./scripts/aws/conf/integ-uid2-config.json + cp ./scripts/aws/conf/integ-uid2-config.json ./build/conf/ + +build/conf/integ-euid-config.json: build_artifacts ./scripts/aws/conf/integ-euid-config.json + cp ./scripts/aws/conf/integ-euid-config.json ./build/conf/ + +build/conf/logback.xml: build_artifacts ./scripts/aws/conf/logback.xml + cp ./scripts/aws/conf/logback.xml ./build/conf/ + +build/Dockerfile: build_artifacts ./scripts/aws/eks/enclave/Dockerfile + cp ./scripts/aws/eks/enclave/Dockerfile ./build/ + +build/proxies.nitro.yaml: build_artifacts ./scripts/aws/eks/enclave/proxies.nitro.yaml + cp ./scripts/aws/eks/enclave/proxies.nitro.yaml ./build/ + +build/syslog-ng-client.conf: build_artifacts ./scripts/aws/syslog-ng/syslog-ng-client.conf + cp ./scripts/aws/syslog-ng/syslog-ng-client.conf ./build/ + +build/syslog-ng-core_4.6.0-1_amd64.deb: build_artifacts ./scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb + cp ./scripts/aws/syslog-ng/client/syslog-ng-core_4.6.0-1_amd64.deb ./build/ + +build/syslog-ng-ose-pub.asc: build_artifacts ./scripts/aws/syslog-ng/client/syslog-ng-ose-pub.asc + cp ./scripts/aws/syslog-ng/client/syslog-ng-ose-pub.asc ./build/ + +build/entrypoint.sh: build_artifacts + cp ./scripts/aws/entrypoint.sh ./build/ + +################################################################################################################################################################## + +# Artifacts + +.PHONY: build_artifacts + +build_artifacts: build/build_artifacts.stamp + +build/build_artifacts.stamp: Dockerfile.nitro.builder + docker build -t uid2-nitro-builder -f Dockerfile.nitro.builder . + docker create --name uid2-nitro-builder uid2-nitro-builder + docker cp uid2-nitro-builder:/build . + docker rm uid2-nitro-builder + mkdir -p build/conf + touch build/build_artifacts.stamp diff --git a/scripts/aws/eks/enclave/Dockerfile b/scripts/aws/eks/enclave/Dockerfile new file mode 100644 index 000000000..8ea0d9cec --- /dev/null +++ b/scripts/aws/eks/enclave/Dockerfile @@ -0,0 +1,49 @@ +# https://hub.docker.com/layers/library/eclipse-temurin/21-jre-jammy/images/sha256-3186dd88a59659929855a6bb785b0528c812eb0b03d97fd6e2221526547ed322?context=explore +FROM eclipse-temurin:21-jre-jammy + +WORKDIR /app + +ARG JAR_NAME=uid2-operator +ARG JAR_VERSION=1.0.0 +ARG IMAGE_VERSION=1.0.0.unknownhash +ARG IDENTITY_SCOPE=UID2 + +ENV JAR_NAME=${JAR_NAME} +ENV JAR_VERSION=${JAR_VERSION} +ENV IMAGE_VERSION=${IMAGE_VERSION} +ENV IDENTITY_SCOPE=${IDENTITY_SCOPE} +ENV ENCLAVE_ENVIRONMENT="aws-nitro" +ENV UID2_CONFIG_SECRET_KEY="uid2-operator-config-key" + +COPY ./syslog-ng-core_4.6.0-1_amd64.deb /app/dep/ +COPY ./syslog-ng-ose-pub.asc /app/dep/ + +RUN echo "deb http://security.ubuntu.com/ubuntu focal-security main" | tee -a /etc/apt/sources.list \ + && apt update -y \ + && apt install -y pkg-config libssl-dev libssl1.1 net-tools curl jq netcat python3 python3-pip libcap2 libivykis0 libjson-c5 libnet1 libwrap0 \ + && apt-key add /app/dep/syslog-ng-ose-pub.asc \ + && apt-get install /app/dep/syslog-ng-core_4.6.0-1_amd64.deb \ + && rm -rf /var/lib/apt/lists/* \ + && apt-key del 6694369F +RUN pip3 install boto3==1.16.9 + +COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar +COPY ./static /app/static +COPY ./libjnsm.so /app/lib/ +COPY ./vsockpx /app/ +COPY ./load_config.py /app/ +COPY ./make_config.py /app/ +COPY ./entrypoint.sh /app/ +COPY ./proxies.nitro.yaml /app/ +COPY ./conf/default-config.json /app/conf/ +COPY ./conf/prod-uid2-config.json /app/conf/ +COPY ./conf/integ-uid2-config.json /app/conf/ +COPY ./conf/prod-euid-config.json /app/conf/ +COPY ./conf/integ-euid-config.json /app/conf/ +COPY ./conf/*.xml /app/conf/ +COPY ./syslog-ng-client.conf /etc/syslog-ng/syslog-ng.conf + +RUN chmod +x /app/vsockpx && chmod +x /app/entrypoint.sh + + +CMD ["/app/entrypoint.sh"] diff --git a/scripts/aws/eks/enclave/entrypoint.sh b/scripts/aws/eks/enclave/entrypoint.sh new file mode 100644 index 000000000..2b49660cc --- /dev/null +++ b/scripts/aws/eks/enclave/entrypoint.sh @@ -0,0 +1,115 @@ +#!/bin/bash -eufx + +set -o pipefail +ulimit -n 65536 + +# -- setup loopback device +echo "Setting up loopback device..." +ifconfig lo 127.0.0.1 + +# -- start vsock proxy +echo "Starting vsock proxy..." +/app/vsockpx --config /app/proxies.nitro.yaml --daemon --workers $(( $(nproc) * 2 )) --log-level 3 + +# -- setup syslog-ng +echo "Starting syslog-ng..." +/usr/sbin/syslog-ng --verbose + +# -- load env vars via proxy +echo "Loading env vars via proxy..." + +TOKEN=$(curl -x socks5h://127.0.0.1:3305 --request PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 3600") +USER_DATA=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/user-data --header "X-aws-ec2-metadata-token: $TOKEN") +if [ "${IDENTITY_SCOPE}" = "UID2" ]; then + UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep UID2_CONFIG_SECRET_KEY=)" =~ ^export\ UID2_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "uid2-operator-config-key") +elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then + UID2_CONFIG_SECRET_KEY=$([[ "$(echo "${USER_DATA}" | grep EUID_CONFIG_SECRET_KEY=)" =~ ^export\ EUID_CONFIG_SECRET_KEY=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "euid-operator-config-key") +else + echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" + exit 1 +fi +CORE_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep CORE_BASE_URL=)" =~ ^export\ CORE_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") +OPTOUT_BASE_URL=$([[ "$(echo "${USER_DATA}" | grep OPTOUT_BASE_URL=)" =~ ^export\ OPTOUT_BASE_URL=\"(.*)\"$ ]] && echo "${BASH_REMATCH[1]}" || echo "") + +echo "UID2_CONFIG_SECRET_KEY=${UID2_CONFIG_SECRET_KEY}" +echo "CORE_BASE_URL=${CORE_BASE_URL}" +echo "OPTOUT_BASE_URL=${OPTOUT_BASE_URL}" + +export AWS_REGION_NAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/dynamic/instance-identity/document/ --header "X-aws-ec2-metadata-token: $TOKEN" | jq -r ".region") +echo "AWS_REGION_NAME=${AWS_REGION_NAME}" +echo "127.0.0.1 secretsmanager.${AWS_REGION_NAME}.amazonaws.com" >> /etc/hosts + +IAM_ROLE=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/iam/security-credentials/ --header "X-aws-ec2-metadata-token: $TOKEN") +echo "IAM_ROLE=${IAM_ROLE}" + +SECURITY_CREDS=$(curl -s -x socks5h://127.0.0.1:3305 "http://169.254.169.254/latest/meta-data/iam/security-credentials/${IAM_ROLE}" --header "X-aws-ec2-metadata-token: $TOKEN") +export AWS_ACCESS_KEY_ID=$(echo $SECURITY_CREDS | jq -r ".AccessKeyId") +export AWS_SECRET_KEY=$(echo $SECURITY_CREDS | jq -r ".SecretAccessKey") +export AWS_SESSION_TOKEN=$(echo $SECURITY_CREDS | jq -r ".Token") + +# -- load configs via proxy +echo "Loading config overrides..." +export OVERRIDES_CONFIG="/app/conf/config-overrides.json" +python3 /app/load_config.py > "${OVERRIDES_CONFIG}" + +export DEPLOYMENT_ENVIRONMENT=$(jq -r ".environment" < "${OVERRIDES_CONFIG}") +echo "DEPLOYMENT_ENVIRONMENT=${DEPLOYMENT_ENVIRONMENT}" +if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then + echo "DEPLOYMENT_ENVIRONMENT cannot be empty" + exit 1 +fi +if [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "integ" ]; then + echo "Unrecognized DEPLOYMENT_ENVIRONMENT ${DEPLOYMENT_ENVIRONMENT}" + exit 1 +fi + +echo "Loading config final..." +export FINAL_CONFIG="/app/conf/config-final.json" +if [ "${IDENTITY_SCOPE}" = "UID2" ]; then + python3 /app/make_config.py /app/conf/prod-uid2-config.json /app/conf/integ-uid2-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} +elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then + python3 /app/make_config.py /app/conf/prod-euid-config.json /app/conf/integ-euid-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG} +else + echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}" + exit 1 +fi + +get_config_value() { + jq -r ".\"$1\"" ${FINAL_CONFIG} +} + +# -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided +# -- using hardcoded domains is fine because they should not be changed frequently +if [ -n "${CORE_BASE_URL}" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then + echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..." + + sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://core-prod.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://core.integ.euid.eu#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://core.prod.euid.eu#${CORE_BASE_URL}#g" "${FINAL_CONFIG}" + + sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout-prod.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout.integ.euid.eu#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" + sed -i "s#https://optout.prod.euid.eu#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}" +fi + +cat "${FINAL_CONFIG}" + +HOSTNAME=$(curl -s -x socks5h://127.0.0.1:3305 http://169.254.169.254/latest/meta-data/local-hostname --header "X-aws-ec2-metadata-token: $TOKEN") +echo "HOSTNAME=${HOSTNAME}" + +# -- set pwd to /app so we can find default configs +cd /app + +# -- start operator +echo "Starting Java application..." +java \ + -XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \ + -Djava.security.egd=file:/dev/./urandom \ + -Djava.library.path=/app/lib \ + -Dvertx-config-path="${FINAL_CONFIG}" \ + -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory \ + -Dlogback.configurationFile=./conf/logback.xml \ + -Dhttp_proxy=socks5://127.0.0.1:3305 \ + -jar /app/"${JAR_NAME}"-"${JAR_VERSION}".jar > /home/start.txt 2>&1 diff --git a/scripts/aws/eks/enclave/proxies.nitro.yaml b/scripts/aws/eks/enclave/proxies.nitro.yaml new file mode 100644 index 000000000..feca3a75d --- /dev/null +++ b/scripts/aws/eks/enclave/proxies.nitro.yaml @@ -0,0 +1,26 @@ +--- + +uid-operator-in: + service: direct + listen: vsock://-1:8080 + connect: tcp://127.0.0.1:8080 + +prometheus-server: + service: direct + listen: vsock://-1:9080 + connect: tcp://127.0.0.1:9080 + +socks5h-proxy: + service: direct + listen: tcp://127.0.0.1:3305 + connect: vsock://3:3305 + +aws-service-proxy: + service: direct + listen: tcp://127.0.0.1:443 + connect: vsock://3:3308 + +syslogng: + service: direct + listen: tcp://127.0.0.1:2011 + connect: vsock://3:2011 diff --git a/scripts/aws/eks/Dockerfile b/scripts/aws/eks/pod/Dockerfile similarity index 100% rename from scripts/aws/eks/Dockerfile rename to scripts/aws/eks/pod/Dockerfile diff --git a/scripts/aws/eks/entrypoint.sh b/scripts/aws/eks/pod/entrypoint.sh similarity index 100% rename from scripts/aws/eks/entrypoint.sh rename to scripts/aws/eks/pod/entrypoint.sh diff --git a/scripts/aws/eks/pod/proxies.host.yaml b/scripts/aws/eks/pod/proxies.host.yaml new file mode 100644 index 000000000..5a2ae0623 --- /dev/null +++ b/scripts/aws/eks/pod/proxies.host.yaml @@ -0,0 +1,21 @@ +--- + +socks5h-proxy: + service: direct + listen: vsock://-1:3305 + connect: tcp://127.0.0.1:3306 + +operator-service: + service: direct + listen: tcp://0.0.0.0:80 + connect: vsock://42:8080 + +operator-prometheus: + service: direct + listen: tcp://0.0.0.0:9080 + connect: vsock://42:9080 + +syslogng: + service: direct + listen: vsock://-1:2011 + connect: tcp://127.0.0.1:2011 From d5a67cb9abbf74461ced5330f8ac765d2bd5ddcc Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 04:30:55 +0000 Subject: [PATCH 0637/1116] [CI Pipeline] Released Snapshot version: 5.37.124-alpha-19-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1e0856943..611e65e01 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.123 + 5.37.124-alpha-19-SNAPSHOT UTF-8 From 738af3e37d501666abf3a0693c82d177bce1b17b Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 16 Jul 2024 21:40:45 +0000 Subject: [PATCH 0638/1116] [CI Pipeline] Released Patch version: 5.37.127 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1e0856943..4afd18bc6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.123 + 5.37.127 UTF-8 From f94574ea4182f1cfa83543149c47bf2b5861583d Mon Sep 17 00:00:00 2001 From: "ian.nara" Date: Tue, 16 Jul 2024 18:12:04 -0600 Subject: [PATCH 0639/1116] unrecognized paths OOM fix --- src/main/java/com/uid2/operator/Const.java | 1 + src/main/java/com/uid2/operator/Main.java | 6 +- .../monitoring/StatsCollectorVerticle.java | 14 ++++- .../com/uid2/operator/vertx/Endpoints.java | 59 +++++++++++++++++ .../operator/vertx/UIDOperatorVerticle.java | 55 ++++++++-------- .../operator/StatsCollectorVerticleTest.java | 63 ++++++++++++++++++- 6 files changed, 165 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/uid2/operator/vertx/Endpoints.java diff --git a/src/main/java/com/uid2/operator/Const.java b/src/main/java/com/uid2/operator/Const.java index 48dd16648..09d183ddd 100644 --- a/src/main/java/com/uid2/operator/Const.java +++ b/src/main/java/com/uid2/operator/Const.java @@ -25,5 +25,6 @@ public class Config extends com.uid2.shared.Const.Config { public static final String GcpSecretVersionNameProp = "gcp_secret_version_name"; public static final String OptOutStatusApiEnabled = "optout_status_api_enabled"; public static final String OptOutStatusMaxRequestSize = "optout_status_max_request_size"; + public static String MaxInvalidPaths = "logging_limit_max_invalid_paths_per_interval"; } } diff --git a/src/main/java/com/uid2/operator/Main.java b/src/main/java/com/uid2/operator/Main.java index 69eb83c19..37e06fbc0 100644 --- a/src/main/java/com/uid2/operator/Main.java +++ b/src/main/java/com/uid2/operator/Main.java @@ -9,6 +9,7 @@ import com.uid2.operator.monitoring.StatsCollectorVerticle; import com.uid2.operator.service.SecureLinkValidatorService; import com.uid2.operator.service.ShutdownService; +import com.uid2.operator.vertx.Endpoints; import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.operator.store.CloudSyncOptOutStore; import com.uid2.operator.store.OptOutCloudStorage; @@ -363,7 +364,7 @@ private Future createAndDeployCloudSyncStoreVerticle(String name, ICloud private Future createAndDeployStatsCollector() { Promise promise = Promise.promise(); - StatsCollectorVerticle statsCollectorVerticle = new StatsCollectorVerticle(60000); + StatsCollectorVerticle statsCollectorVerticle = new StatsCollectorVerticle(60000, config.getInteger(Const.Config.MaxInvalidPaths, 50)); vertx.deployVerticle(statsCollectorVerticle, promise); _statsCollectorQueue = statsCollectorVerticle; return promise.future(); @@ -425,7 +426,8 @@ private static void setupMetrics(MicrometerMetricsOptions metricOptions) { .meterFilter(new PrometheusRenameFilter()) .meterFilter(MeterFilter.replaceTagValues(Label.HTTP_PATH.toString(), actualPath -> { try { - return HttpUtils.normalizePath(actualPath).split("\\?")[0]; + String normalized = HttpUtils.normalizePath(actualPath).split("\\?")[0]; + return Endpoints.pathSet().contains(normalized) ? normalized : "/unknown"; } catch (IllegalArgumentException e) { return actualPath; } diff --git a/src/main/java/com/uid2/operator/monitoring/StatsCollectorVerticle.java b/src/main/java/com/uid2/operator/monitoring/StatsCollectorVerticle.java index 26c0653e0..faebfae5f 100644 --- a/src/main/java/com/uid2/operator/monitoring/StatsCollectorVerticle.java +++ b/src/main/java/com/uid2/operator/monitoring/StatsCollectorVerticle.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.uid2.operator.Const; import com.uid2.operator.model.StatsCollectorMessageItem; +import com.uid2.operator.vertx.Endpoints; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Metrics; import io.vertx.core.AbstractVerticle; @@ -24,6 +25,7 @@ public class StatsCollectorVerticle extends AbstractVerticle implements IStatsCo private HashMap pathMap; private static final int MAX_AVAILABLE = 1000; + private final int maxInvalidPaths; private final Duration jsonProcessingInterval; private Instant lastJsonProcessTime; @@ -39,13 +41,14 @@ public class StatsCollectorVerticle extends AbstractVerticle implements IStatsCo private final ObjectMapper mapper; private final Counter queueFullCounter; - public StatsCollectorVerticle(long jsonIntervalMS) { + public StatsCollectorVerticle(long jsonIntervalMS, int maxInvalidPaths) { pathMap = new HashMap<>(); _statsCollectorCount = new AtomicInteger(); _runningSerializer = false; jsonProcessingInterval = Duration.ofMillis(jsonIntervalMS); + this.maxInvalidPaths = maxInvalidPaths; logCycleSkipperCounter = Counter .builder("uid2.api_usage_log_cycle_skipped") @@ -113,7 +116,11 @@ public void handleMessage(Message message) { EndpointStat endpointStat = new EndpointStat(endpoint, siteId, apiVersion, domain); - pathMap.merge(path, endpointStat, this::mergeEndpoint); + Set endpoints = Endpoints.pathSet(); + if(endpoints.contains(path) || pathMap.containsKey(path) || (pathMap.size() < this.maxInvalidPaths + endpoints.size() && messageItem.getApiContact() != null)) { + pathMap.merge(path, endpointStat, this::mergeEndpoint); + } + _statsCollectorCount.decrementAndGet(); @@ -123,6 +130,9 @@ public void handleMessage(Message message) { logCycleSkipperCounter.increment(); } else { _runningSerializer = true; + if(pathMap.size() == this.maxInvalidPaths + endpoints.size()) { + LOGGER.error("max invalid paths reached; a large number of invalid paths have been requested from authenticated participants"); + } Object[] stats = pathMap.values().toArray(); this.jsonSerializerExecutor.executeBlocking( promise -> promise.complete(this.serializeToLogs(stats)), diff --git a/src/main/java/com/uid2/operator/vertx/Endpoints.java b/src/main/java/com/uid2/operator/vertx/Endpoints.java new file mode 100644 index 000000000..2643f943b --- /dev/null +++ b/src/main/java/com/uid2/operator/vertx/Endpoints.java @@ -0,0 +1,59 @@ +package com.uid2.operator.vertx; + +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public enum Endpoints { + OPS_HEALTHCHECK("/ops/healthcheck"), + + V0_KEY_LATEST("/key/latest"), + V0_TOKEN_GENERATE("/token/generate"), + V0_TOKEN_REFRESH("/token/refresh"), + V0_TOKEN_VALIDATE("/token/validate"), + V0_IDENTITY_MAP("/identity/map"), + V0_TOKEN_LOGOUT("/token/logout"), + + V1_TOKEN_GENERATE("/v1/token/generate"), + V1_TOKEN_VALIDATE("/v1/token/validate"), + V1_TOKEN_REFRESH("/v1/token/refresh"), + V1_IDENTITY_BUCKETS("/v1/identity/buckets"), + V1_IDENTITY_MAP("/v1/identity/map"), + V1_KEY_LATEST("/v1/key/latest"), + + V2_TOKEN_GENERATE("/v2/token/generate"), + V2_TOKEN_REFRESH("/v2/token/refresh"), + V2_TOKEN_VALIDATE("/v2/token/validate"), + V2_IDENTITY_BUCKETS("/v2/identity/buckets"), + V2_IDENTITY_MAP("/v2/identity/map"), + V2_KEY_LATEST("/v2/key/latest"), + V2_KEY_SHARING("/v2/key/sharing"), + V2_KEY_BIDSTREAM("/v2/key/bidstream"), + V2_TOKEN_LOGOUT("/v2/token/logout"), + V2_OPTOUT_STATUS("/v2/optout/status"), + V2_TOKEN_CLIENTGENERATE("/v2/token/client-generate"), + + EUID_SDK_1_0_0("/static/js/euid-sdk-1.0.0.js"), + OPENID_SDK_1_0("/static/js/openid-sdk-1.0.js"), + UID2_ESP_0_0_1A("/static/js/uid2-esp-0.0.1a.js"), + UID2_SDK_0_0_1A("/static/js/uid2-sdk-0.0.1a.js"), + UID2_SDK_0_0_1A_SOURCE("/static/js/uid2-sdk-0.0.1a-source.ts"), + UID2_SDK_0_0_1B("/static/js/uid2-sdk-0.0.1b.js"), + UID2_SDK_1_0_0("/static/js/uid2-sdk-1.0.0.js"), + UID2_SDK_2_0_0("/static/js/uid2-sdk-2.0.0.js") + ; + private final String path; + + Endpoints(final String path) { + this.path = path; + } + + public static Set pathSet() { + return Stream.of(Endpoints.values()).map(Endpoints::toString).collect(Collectors.toSet()); + } + + @Override + public String toString() { + return path; + } +} diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 372935da7..b3612f187 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -69,6 +69,7 @@ import static com.uid2.operator.IdentityConst.*; import static com.uid2.operator.service.ResponseUtil.*; +import static com.uid2.operator.vertx.Endpoints.*; public class UIDOperatorVerticle extends AbstractVerticle { private static final Logger LOGGER = LoggerFactory.getLogger(UIDOperatorVerticle.class); @@ -236,28 +237,28 @@ private Router createRoutesSetup() throws IOException { setupV2Routes(router, bodyHandler); // Static and health check - router.get("/ops/healthcheck").handler(this::handleHealthCheck); + router.get(OPS_HEALTHCHECK.toString()).handler(this::handleHealthCheck); if (this.config.getBoolean(Const.Config.AllowLegacyAPIProp, true)) { // V1 APIs - router.get("/v1/token/generate").handler(auth.handleV1(this::handleTokenGenerateV1, Role.GENERATOR)); - router.get("/v1/token/validate").handler(this::handleTokenValidateV1); - router.get("/v1/token/refresh").handler(auth.handleWithOptionalAuth(this::handleTokenRefreshV1)); - router.get("/v1/identity/buckets").handler(auth.handle(this::handleBucketsV1, Role.MAPPER)); - router.get("/v1/identity/map").handler(auth.handle(this::handleIdentityMapV1, Role.MAPPER)); - router.post("/v1/identity/map").handler(bodyHandler).handler(auth.handle(this::handleIdentityMapBatchV1, Role.MAPPER)); - router.get("/v1/key/latest").handler(auth.handle(this::handleKeysRequestV1, Role.ID_READER)); + router.get(V1_TOKEN_GENERATE.toString()).handler(auth.handleV1(this::handleTokenGenerateV1, Role.GENERATOR)); + router.get(V1_TOKEN_VALIDATE.toString()).handler(this::handleTokenValidateV1); + router.get(V1_TOKEN_REFRESH.toString()).handler(auth.handleWithOptionalAuth(this::handleTokenRefreshV1)); + router.get(V1_IDENTITY_BUCKETS.toString()).handler(auth.handle(this::handleBucketsV1, Role.MAPPER)); + router.get(V1_IDENTITY_MAP.toString()).handler(auth.handle(this::handleIdentityMapV1, Role.MAPPER)); + router.post(V1_IDENTITY_MAP.toString()).handler(bodyHandler).handler(auth.handle(this::handleIdentityMapBatchV1, Role.MAPPER)); + router.get(V1_KEY_LATEST.toString()).handler(auth.handle(this::handleKeysRequestV1, Role.ID_READER)); // Deprecated APIs - router.get("/key/latest").handler(auth.handle(this::handleKeysRequest, Role.ID_READER)); - router.get("/token/generate").handler(auth.handle(this::handleTokenGenerate, Role.GENERATOR)); - router.get("/token/refresh").handler(this::handleTokenRefresh); - router.get("/token/validate").handler(this::handleValidate); - router.get("/identity/map").handler(auth.handle(this::handleIdentityMap, Role.MAPPER)); - router.post("/identity/map").handler(bodyHandler).handler(auth.handle(this::handleIdentityMapBatch, Role.MAPPER)); + router.get(V0_KEY_LATEST.toString()).handler(auth.handle(this::handleKeysRequest, Role.ID_READER)); + router.get(V0_TOKEN_GENERATE.toString()).handler(auth.handle(this::handleTokenGenerate, Role.GENERATOR)); + router.get(V0_TOKEN_REFRESH.toString()).handler(this::handleTokenRefresh); + router.get(V0_TOKEN_VALIDATE.toString()).handler(this::handleValidate); + router.get(V0_IDENTITY_MAP.toString()).handler(auth.handle(this::handleIdentityMap, Role.MAPPER)); + router.post(V0_IDENTITY_MAP.toString()).handler(bodyHandler).handler(auth.handle(this::handleIdentityMapBatch, Role.MAPPER)); // Internal service APIs - router.get("/token/logout").handler(auth.handle(this::handleLogoutAsync, Role.OPTOUT)); + router.get(V0_TOKEN_LOGOUT.toString()).handler(auth.handle(this::handleLogoutAsync, Role.OPTOUT)); // only uncomment to do local testing //router.get("/internal/optout/get").handler(auth.loopbackOnly(this::handleOptOutGet)); @@ -268,36 +269,34 @@ private Router createRoutesSetup() throws IOException { } private void setupV2Routes(Router mainRouter, BodyHandler bodyHandler) { - final Router v2Router = Router.router(vertx); - v2Router.post("/token/generate").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_TOKEN_GENERATE.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handleTokenGenerate(rc, this::handleTokenGenerateV2), Role.GENERATOR)); - v2Router.post("/token/refresh").handler(bodyHandler).handler(auth.handleWithOptionalAuth( + mainRouter.post(V2_TOKEN_REFRESH.toString()).handler(bodyHandler).handler(auth.handleWithOptionalAuth( rc -> v2PayloadHandler.handleTokenRefresh(rc, this::handleTokenRefreshV2))); - v2Router.post("/token/validate").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_TOKEN_VALIDATE.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleTokenValidateV2), Role.GENERATOR)); - v2Router.post("/identity/buckets").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_IDENTITY_BUCKETS.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleBucketsV2), Role.MAPPER)); - v2Router.post("/identity/map").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_IDENTITY_MAP.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleIdentityMapV2), Role.MAPPER)); - v2Router.post("/key/latest").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_KEY_LATEST.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleKeysRequestV2), Role.ID_READER)); - v2Router.post("/key/sharing").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_KEY_SHARING.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleKeysSharing), Role.SHARER, Role.ID_READER)); - v2Router.post("/key/bidstream").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_KEY_BIDSTREAM.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleKeysBidstream), Role.ID_READER)); - v2Router.post("/token/logout").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_TOKEN_LOGOUT.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handleAsync(rc, this::handleLogoutAsyncV2), Role.OPTOUT)); if (this.optOutStatusApiEnabled) { - v2Router.post("/optout/status").handler(bodyHandler).handler(auth.handleV1( + mainRouter.post(V2_OPTOUT_STATUS.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleOptoutStatus), Role.MAPPER, Role.SHARER, Role.ID_READER)); } if (this.clientSideTokenGenerate) - v2Router.post("/token/client-generate").handler(bodyHandler).handler(this::handleClientSideTokenGenerate); + mainRouter.post(V2_TOKEN_CLIENTGENERATE.toString()).handler(bodyHandler).handler(this::handleClientSideTokenGenerate); - mainRouter.route("/v2/*").subRouter(v2Router); } diff --git a/src/test/java/com/uid2/operator/StatsCollectorVerticleTest.java b/src/test/java/com/uid2/operator/StatsCollectorVerticleTest.java index 81162e69f..a633d6cd7 100644 --- a/src/test/java/com/uid2/operator/StatsCollectorVerticleTest.java +++ b/src/test/java/com/uid2/operator/StatsCollectorVerticleTest.java @@ -1,9 +1,13 @@ package com.uid2.operator; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.uid2.operator.model.StatsCollectorMessageItem; import com.uid2.operator.monitoring.StatsCollectorVerticle; +import com.uid2.operator.vertx.Endpoints; import io.vertx.core.Vertx; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; @@ -11,16 +15,19 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.LoggerFactory; +import java.util.Set; import java.util.concurrent.TimeUnit; @ExtendWith(VertxExtension.class) public class StatsCollectorVerticleTest { + private static final int MAX_INVALID_PATHS = 5; private StatsCollectorVerticle verticle; @BeforeEach void deployVerticle(Vertx vertx, VertxTestContext testContext) throws Throwable { - verticle = new StatsCollectorVerticle(1000); + verticle = new StatsCollectorVerticle(1000, MAX_INVALID_PATHS); vertx.deployVerticle(verticle, testContext.succeeding(id -> testContext.completeNow())); } @@ -83,4 +90,58 @@ void testJSONSerializeWithV2AndUnknownPaths(Vertx vertx, VertxTestContext testCo testContext.completeNow(); } + + @Test + void invalidPathsFiltering(Vertx vertx, VertxTestContext testContext) throws InterruptedException, JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + Set validEndpoints = Endpoints.pathSet(); + + for(String endpoint : validEndpoints) { + StatsCollectorMessageItem messageItem = new StatsCollectorMessageItem(endpoint, "https://test.com", "test", 1); + vertx.eventBus().send(Const.Config.StatsCollectorEventBus, mapper.writeValueAsString(messageItem)); + } + + for(int i = 0; i < MAX_INVALID_PATHS + 5; i++) { + StatsCollectorMessageItem messageItem = new StatsCollectorMessageItem("/bad" + i, "https://test.com", "test", 1); + vertx.eventBus().send(Const.Config.StatsCollectorEventBus, mapper.writeValueAsString(messageItem)); + } + + testContext.awaitCompletion(2000, TimeUnit.MILLISECONDS); + + String results = verticle.getEndpointStats(); + + for(String endpoint: validEndpoints) { + String withoutVersion = endpoint; + if (endpoint.startsWith("/v1/") || endpoint.startsWith("/v2/")) { + withoutVersion = endpoint.substring(4); + } else if (endpoint.startsWith("/")) { + withoutVersion = endpoint.substring(1); + } + + String expected = "{\"endpoint\":\"" + withoutVersion + "\",\"siteId\":1,"; + Assertions.assertTrue(results.contains(expected)); + } + + for(int i = 0; i < MAX_INVALID_PATHS; i++) { + String expected = "{\"endpoint\":\"bad" + i + "\",\"siteId\":1,\"apiVersion\":\"v0\",\"domainList\":[{\"domain\":\"test.com\",\"count\":1,\"apiContact\":\"test\"}]}"; + Assertions.assertTrue(results.contains(expected)); + } + for(int i = MAX_INVALID_PATHS; i < MAX_INVALID_PATHS + 5; i++) { + String expected = "{\"endpoint\":\"bad" + i + "\",\"siteId\":1,\"apiVersion\":\"v0\",\"domainList\":[{\"domain\":\"test.com\",\"count\":1,\"apiContact\":\"test\"}]}"; + Assertions.assertFalse(results.contains(expected)); + } + + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(StatsCollectorVerticle.class)).addAppender(logWatcher); + + StatsCollectorMessageItem messageItem = new StatsCollectorMessageItem("/triggerSerialize", "https://test.com", "test", 1); + vertx.eventBus().send(Const.Config.StatsCollectorEventBus, mapper.writeValueAsString(messageItem)); + + testContext.awaitCompletion(1000, TimeUnit.MILLISECONDS); + + Assertions.assertTrue(logWatcher.list.get(0).getFormattedMessage().contains("max invalid paths reached; a large number of invalid paths have been requested from authenticated participants")); + + testContext.completeNow(); + } } From 3ef100c75a749db75d619075366a4eed9d4ccdb9 Mon Sep 17 00:00:00 2001 From: Katherine Chen Date: Wed, 17 Jul 2024 14:20:26 +1000 Subject: [PATCH 0640/1116] Revert action ref to main (#748) --- .github/workflows/publish-aws-eks-nitro-enclave-docker.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml index 356eefdc0..ad6c6fdad 100644 --- a/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-eks-nitro-enclave-docker.yaml @@ -137,7 +137,7 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@main with: identity_scope: uid2 artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -159,7 +159,7 @@ jobs: steps: - name: Build Docker Image for EKS Pod id: build_docker_image - uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@tjm-UID2-3706-eks-eif-build + uses: IABTechLab/uid2-operator/.github/actions/build_eks_docker_image@main with: identity_scope: euid artifacts_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid From 56e1e46f92ed05932400991130f71766e67276d7 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 18 Jul 2024 01:37:01 +0000 Subject: [PATCH 0641/1116] [CI Pipeline] Released Patch version: 5.37.168 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 611e65e01..b221c867d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.37.124-alpha-19-SNAPSHOT + 5.37.168 UTF-8 From d8f25169ef271c69e09dc068a9d13ae6cc4fe3fe Mon Sep 17 00:00:00 2001 From: Thomas Manson Date: Thu, 18 Jul 2024 15:48:10 +1000 Subject: [PATCH 0642/1116] Update the eif and ami builds for syslog-ng --- .github/actions/build_aws_eif/action.yaml | 8 ++- .../publish-aws-nitro-enclave-docker.yaml | 14 ++--- .../ivykis-0.43-1.amzn2023.x86_64.rpm | Bin 0 -> 47901 bytes .../libnet-1.2-2.amzn2023.0.2.x86_64.rpm | Bin 0 -> 60612 bytes .../aws/syslog-ng/server_al_2023/pubkey.gpg | 19 +++++++ ...g-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm | Bin 0 -> 1074551 bytes ...e-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm | Bin 0 -> 9229 bytes .../uid2-operator-ami/ansible/playbook.yml | 53 ++++++++++-------- 8 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 scripts/aws/syslog-ng/server_al_2023/ivykis-0.43-1.amzn2023.x86_64.rpm create mode 100644 scripts/aws/syslog-ng/server_al_2023/libnet-1.2-2.amzn2023.0.2.x86_64.rpm create mode 100644 scripts/aws/syslog-ng/server_al_2023/pubkey.gpg create mode 100644 scripts/aws/syslog-ng/server_al_2023/syslog-ng-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm create mode 100644 scripts/aws/syslog-ng/server_al_2023/syslog-ng-logrotate-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm diff --git a/.github/actions/build_aws_eif/action.yaml b/.github/actions/build_aws_eif/action.yaml index b212db8d1..3705b98f0 100644 --- a/.github/actions/build_aws_eif/action.yaml +++ b/.github/actions/build_aws_eif/action.yaml @@ -77,9 +77,11 @@ runs: cp ./scripts/aws/uid2operator.service ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/pipeline/$(cat ${{ steps.buildFolder.outputs.BUILD_FOLDER }}/identity_scope.txt)_VERSION ${ARTIFACTS_OUTPUT_DIR}/VERSION cp ./scripts/aws/syslog-ng/syslog-ng-server.conf ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/syslog-ng/server/syslog-ng-pubkey.gpg ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/syslog-ng/server/syslog-ng-4.6.0-1.el7.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ - cp ./scripts/aws/syslog-ng/server/syslog-ng-amazon23.repo ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server_al_2023/ivykis-0.43-1.amzn2023.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server_al_2023/libnet-1.2-2.amzn2023.0.2.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server_al_2023/pubkey.gpg ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server_al_2023/syslog-ng-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ + cp ./scripts/aws/syslog-ng/server_al_2023/syslog-ng-logrotate-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/logrotate/operator-logrotate.conf ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/logrotate/logrotate ${ARTIFACTS_OUTPUT_DIR}/ cp ./scripts/aws/logrotate/logrotateDaily ${ARTIFACTS_OUTPUT_DIR}/ diff --git a/.github/workflows/publish-aws-nitro-enclave-docker.yaml b/.github/workflows/publish-aws-nitro-enclave-docker.yaml index ff7fb0375..140b0f465 100644 --- a/.github/workflows/publish-aws-nitro-enclave-docker.yaml +++ b/.github/workflows/publish-aws-nitro-enclave-docker.yaml @@ -157,7 +157,7 @@ jobs: - name: Build UID2 AWS EIF id: build_uid2_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3729-al2023-syslogng with: identity_scope: uid2 artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2 @@ -218,7 +218,7 @@ jobs: - name: Build EUID AWS EIF id: build_euid_eif - uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@main + uses: IABTechLab/uid2-operator/.github/actions/build_aws_eif@tjm-UID2-3729-al2023-syslogng with: identity_scope: euid artifacts_base_output_dir: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid @@ -278,11 +278,11 @@ jobs: path: ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/manifests if-no-files-found: error - - name: Generate release archive files - if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} - run: | - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* - zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* + # - name: Generate release archive files + # if: ${{ inputs.version_number_input == '' && needs.start.outputs.is_release == 'true' }} + # run: | + # zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-uid2-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/uid2/* + # zip -j ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/aws-euid-deployment-artifacts-${{ needs.start.outputs.new_version }}.zip ${{ env.ARTIFACTS_BASE_OUTPUT_DIR }}/euid/* - name: Build changelog id: github_release diff --git a/scripts/aws/syslog-ng/server_al_2023/ivykis-0.43-1.amzn2023.x86_64.rpm b/scripts/aws/syslog-ng/server_al_2023/ivykis-0.43-1.amzn2023.x86_64.rpm new file mode 100644 index 0000000000000000000000000000000000000000..54d655150c3ea09096c46923349be00901687c82 GIT binary patch literal 47901 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 literal 0 HcmV?d00001 diff --git a/scripts/aws/syslog-ng/server_al_2023/libnet-1.2-2.amzn2023.0.2.x86_64.rpm b/scripts/aws/syslog-ng/server_al_2023/libnet-1.2-2.amzn2023.0.2.x86_64.rpm new file mode 100644 index 0000000000000000000000000000000000000000..728677b5a1703ab6769fdf82813259b467367315 GIT binary patch literal 60612 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 AWB>pF literal 0 HcmV?d00001 diff --git a/scripts/aws/syslog-ng/server_al_2023/pubkey.gpg b/scripts/aws/syslog-ng/server_al_2023/pubkey.gpg new file mode 100644 index 000000000..b38729ec0 --- /dev/null +++ b/scripts/aws/syslog-ng/server_al_2023/pubkey.gpg @@ -0,0 +1,19 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBGYw4okBCADnaPDLp32IFXHhKE/e2kusIsiqieECEeLDcfYKT5VGYQD1yQeN +prHxKm8U6dqqvmSd5ehphwrjeXY54XVWOlOT1FZpmFOLgi1XXn0syoMX/cJ2GcOV +M8r4Z0CptDwp6PRvR+sLFGGENR3LueCi0RwHiw7M9jIxxuAuKH55IpWdCCshiFN5 +EE3AGeFbDERteyBywNZc3Q9OZXQ8y8jEp5CH8tbspQU+Qig/kGCjIWRnmkWFM6mT +qdFtgWG4G6nhzvGwoD3J+IPPL02IV7Qywxl6dUBKhrLFPhorPXBSy43wlUZJY9IM +kJK+EfpkSnY4v2tEfnakbHs8k1Tlw8f5exQhABEBAAG0UmN6YW5pa19zeXNsb2ct +bmctYW1hem9uMjMgKE5vbmUpIDxjemFuaWsjc3lzbG9nLW5nLWFtYXpvbjIzQGNv +cHIuZmVkb3JhaG9zdGVkLm9yZz6JAVgEEwEIAEIWIQSCmrP3ftEn1OdcMJPM0E5Y +LFGYWQUCZjDiiQMbLwQFCQlmAYAFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AA +CgkQzNBOWCxRmFm/6AgAxA1kWfcJZMLP1FdvLuadPw4QH2KYqOAIAnGb8+a08CSf +Vwyhb3nFQ6h0K5sfVmrMNikmgu3cOssX/iLbjMJhBoITUkD8jpmQmO7oV6GPn1dT +TIEIb1rYLtCu6/BHniyKNOPgZNmi80I+hTt5rWwOmfLlfMCGP/ob6iLs3yIAz4cE +Oe5lFLMfn9IMmDJC9E5kVP9sjTUWjuW192lTTyyOdPx6m8h2dk+i//8SnYikNXEg +djPNQNxf6pw0TvO8dn4qO4YNrQgfnap3s1QvVgL0tQHDINOs+t01brRMS49KhYF9 +y9OTIIeQw6nUaytecy5A7j5JUIaqxie0SFHqIrB35A== +=IyUG +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/aws/syslog-ng/server_al_2023/syslog-ng-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm b/scripts/aws/syslog-ng/server_al_2023/syslog-ng-4.7.1.104.gcc5a7d9-1.amzn2023.x86_64.rpm new file mode 100644 index 0000000000000000000000000000000000000000..862a03e2fc12d0fd70d81b8b95a2f1600d160d5a GIT binary patch literal 1074551 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

    p%GBkbYPue8Qw*zASmGn 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⪼4|4>94{!D1g< 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 z zx_cs{9hC*!{=;3g=#&r@;PJK8PMN5-lHJT^P>)24__fBgY81KM1s6DH@9r{A?INe* zcy)0zpIzK0$oFmP-K8b-&kQ>X9jSOS3G=QAjM?5qTOo>y0Jj@Wioz^8&oDh+^cy?M ziP}(bHC5XkE@-x1~Gd@wz21@OReWtQUFqlP~Wk>sH773dZD!NgCDjN%qu#gjUNlmsG7;L5^&}xr7RnGT2YM-s;KXb8c7 z_aa|T4stQX)Wpk$Qw2_a@K^EV&4d>J0?UxJX8aN&8uiS-2Y`oWpJUvd*NNHuiG80%L$sKW}Gw zqomEK*1;QZ{B%LU2Fm4(^eZ~?X+M64{nD$=z>CtPo}*8ze8L@xm5w}8guVH%x7RjV zyaEYvlP7MrdMJ0-NswnXwkBOBSW=#ooiutlHiQ#ArbG5|kVxila5k)$$)P8THmoOY zU_HrKsc|kudW%RcSw5*#8Q&p(gBJUCDlJ1%oCss z$Kx*#m%ZfA#na^-kKWE-P4pHruo_C{0v5SbK5eB;1Cqt&O{9jYSc1%mc4Z5O7tYbE zZ3jE|0n~98OUblox8Np7QinmF8;*}y!YJAisx^?6G8irGaqUGg>&@{UX0z+It@Qc7 z@B1NWd^!*%at&8S$i|>|?*o;*EQRamC695M!O`cDQ(p1W9BatZNz4bYqwActN}a)8 z=C2wyL#W?Ka+?TB*etr*{|Uhr^SRmV0S%5@)1(oye>FK~P~jw5Bvl^U!)7oS6oXjA zemiK9A*XmZ-#;1cjoZdr*Pw#8-?d=iBCIyv*mNeJktaJCd7C*YpeQv=7S<#tlXA#j&xuPK{G~ep)~elQL`mkpFNpCR@wtP z>`v;Y>pPK!nQir+;Lzq(>Y$ag!7ya{J#q+q&%;cEJv)R8{`9>c;i!&;)vi4p?N7492{}c+XMLOwXb z2Mv@*5YJr;DC@kGubiP5guWlE1P&WQ3Wf`X-hqqsL=VlwupNa(!BB%7#YV;VG7kO~ z+MADJiBWmGHb4)mc3F~gHvl!>QazWRfavXc_<$aBH$k9eC^nEn!woFm46?y_4$>Rk zh-k6_a?kJk0yRRUgS!rVGDf7!=GzYBL)u})YLz@+ShT5kz|i$s=A(V9fD9W}1ZW5e zj+PN=VT}fV7oo^(ga%6HW{|Bo0)Z0Y5y~0^?HX13iUeHk4V(rHDf-6va`H9kdXKt+ z+7(`inh1cXqD5^0PkLiP)rZh{%?Z-ExTI=yem%O9G(=D#*e9V=L#5(+rKALfUQyUP z!UN#>fL=fnZXgM>CJ;aZ{H4ju?*y;|{BnZhSCD}h7ZU|iIyjlYJ4sRKnNYwpGyVe5 z@#^#QQc{@$`4k-;om4Fx=f*fWs_VMymiEqn|9cH09|8wQlQI54QW1O}l@l4n zO8LQPEG6VDA#DJDB8=cpq8Tj;-qxoF0Ral;Rn>qkR`8NU;9TVZ>x1_(XoFA&PqVZK zh%QpX2-!#>{1%r%&=b5l246KcG|0ZRRP>ST0)dr-2~sx;<%@BR0R@GDAaMXQ3?u

    urc>#BSMZwmX0n@kZ>6cv_9p#x6{ctipE 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%0APN}j$S&$88OfFenPeIAt-*+3b`D+K>^h3f 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

    v#aChOZ>T-u5io5 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%0Dv5@$2{4E97vy|hC^ElXqt$kI#-)0}@S@R)J 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%0Ag(gtAPn=78rN@DCVuzO|so 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 z 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

s4!F%)ZlA?px}z)VQEgagIcSd~^Ge+vCG6 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 z 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